You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB如何通过._id过滤已点赞/点踩用户账号?适配交友应用场景

问题根因分析
  • 逻辑分支错误:原过滤函数使用if (存在点赞记录) {} else if (存在点踩记录) {}的分支结构,只要用户有过点赞记录,就完全不会执行点踩记录的过滤逻辑,反过来也一样,导致大量已操作的用户没有被正确过滤。
  • 遍历修改原数组导致索引异常:用for of遍历原数组的同时调用splice删除元素,数组长度会动态变化,后续遍历的索引会发生偏移,最终出现误删未操作过的用户、漏删已操作用户的问题。
  • 未统一返回响应:过滤完成后没有主动返回结果给前端,只有当用户既没有点赞也没有点踩记录的时候才会返回数据,其余情况前端无法拿到正常响应。
  • 执行效率低:双层循环的时间复杂度为O(n*m),用户量大的时候运算性能会非常差。
修复方案

方案1:修复现有过滤函数

如果要保留独立过滤函数的写法,可直接替换为以下代码:

const filter = async (currentUser, users, req, res, error) => {
  try {
    // 合并所有需要排除的用户ID存入Set,存在性判断时间复杂度为O(1)
    const excludedIds = new Set([
      ...currentUser.likes,
      ...currentUser.dislikes
    ]);
    // 直接过滤生成新数组,不修改原数组,彻底避免索引错乱问题
    const filteredUsers = users.filter(user => !excludedIds.has(user._id.toString()));
    // 统一返回过滤后的结果
    return res.json({ users: filteredUsers });
  } catch (error) {
    console.log(error, "error");
    return res.status(500).json({msg: "用户过滤失败"});
  }
};

方案2:MongoDB查询阶段直接过滤(更优,推荐)

不需要单独维护过滤函数,直接在数据库查询阶段排除已点赞/点踩的用户,减少无效数据查询和传输,数据量越大性能优势越明显:

router.get( "/user/match/:id", authenticateUser, asyncHandler(async (req, res, error) => {
    const currentUser = await User.findOne({ _id: req.params.id });
    if (currentUser.gender === "Male" && currentUser.sexualPreference === "Straight") {
      // 合并所有需要排除的用户ID
      const excludedIds = [...currentUser.likes, ...currentUser.dislikes];
      // 用MongoDB的$nin操作符直接过滤掉不需要展示的用户
      const users = await User.find({ 
        gender: "Female", 
        sexualPreference: "Straight",
        _id: { $nin: excludedIds }
      });
      return res.json({ users });
    }
    // 可在此扩展其他性别/性取向的匹配逻辑
    return res.status(400).json({msg: "暂不支持该匹配条件"});
  })
);

内容的提问来源于stack exchange,提问作者RandyBeans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 03:15:04