【问题标题】:MongoDB - find() with 5 filters and conditions gives different results than no conditionsMongoDB - 具有 5 个过滤器和条件的 find() 给出的结果与没有条件不同
【发布时间】:2022-01-26 18:46:22
【问题描述】:

我编写并测试了一个查询来检索文档,它工作得很好,它完全符合我的要求,当我取出每个过滤器时,它检索到正确的文档。现在,我不想手动评论每个过滤器,而是希望在索引下降时将其基于索引,因此在 index = 4 它应该使用所有过滤器,在 index = 3 它应该使用更少的过滤器,直到在 index = 0 它应该只是获取文件。

运行良好的代码:

    users = await User.find({
      $and: ignoreUsers.map((id) => {
        return { _id: { $ne: new ObjectId(id) } };
      }),
      objectives: { $in: objectives },
      ranking: ranking,
      expLevel: { $gte: expLevel - 1, $lte: expLevel + 1 },
      industries: { $in: industries },
      "skills.self": { $in: skills },
      interests: { $in: interests },
    });

这会产生 1 个正确的文档,但是当我添加 if 条件时,它会产生 5 个不正确的文档。 ranking.<variable> 是数字 1-4,所以如果 index = 4 则所有 if 条件都应该为真,对吧?但他们都没有被处决。只有目标和排名过滤器有效,整个$expr 条件被忽略

        let index = 4;

        // supposed to be in while loop but testing just once does not produce just the 1 document it's supposed to

        const fetchCondUsers = await User.find({
          $and: ignoreUsers.map((id) => {
            return { _id: { $ne: new ObjectId(id) } };
          }),
          objectives: { $in: objectives },
          
          $expr: {
            $cond: {
              if: { $gte: [index, 0] },
              then: {
                ranking: ranking,
              },
              else: "$$REMOVE",
            },
            $cond: {
              if: { $gte: [index, ranking.expLevel] },
              then: {
                $and: [
                  { $gte: ["$expLevel", expLevel - 1] },
                  { $lte: ["$expLevel", expLevel + 1] },
                ],
              },
              else: "$$REMOVE",
            },
            $cond: {
              if: { $gte: [index, ranking.industry] },
              then: {
                industries: { $in: ["$industries", industries] },
              },
              else: "$$REMOVE",
            },
            $cond: {
              if: { $gte: [index, ranking.skills] },
              then: {
                skills: { $in: ["$skills", skills] },
              },
              else: "$$REMOVE",
            },
            $cond: {
              if: { $gte: [index, ranking.interests] },
              then: {
                interests: { $in: ["$interests", interests] },
              },
              else: "$$REMOVE",
            },
          },
        }).limit(limit);

理想情况下,这就是我想要做的

      users = await User.find({
        $and: ignoreUsers.map((id) => {
          return { _id: { $ne: new ObjectId(id) } };
        }),
        objectives: { $in: objectives },
        if (index === 0) ranking: ranking,
        if (index === 1) expLevel: { $gte: expLevel - 1, $lte: expLevel + 1 },
        if (index === 2) industries: { $in: industries },
        if (index === 3) "skills.self": { $in: skills },
        if (index === 4) interests: { $in: interests },
      });

【问题讨论】:

    标签: mongodb mongoose graphql apollo


    【解决方案1】:

    所以在凝视深渊之后,我意识到 javascript........ 一个对象被传递到 find()... 所以我只是将对象取出到它自己的变量中并打破它是这样的:

          while (users.length < limit) {
            const query = {
              $and: ignoreUserObjectIDs.map((oID) => {
                return { _id: { $ne: oID } };
              }),
              objectives: { $in: objectives },
            };
    
            if (index >= 0) {
              query["ranking"] = ranking;
            }
            if (index >= ranking.expLevel) {
              query["expLevel"] = { $gte: expLevel - 1, $lte: expLevel + 1 };
            }
            if (index >= ranking.industry) {
              query["industries"] = { $in: industries };
            }
            if (index >= ranking.skills) {
              query["skills.self"] = { $in: skills };
            }
            if (index >= ranking.interests) {
              query["interests"] = { $in: interests };
            }
    
            const fetchCondUsers = await User.find(query).limit(
              limit - users.length
            );
    
            users = users.concat(fetchCondUsers);
            ignoreUserObjectIDs = ignoreUserObjectIDs.concat(
              fetchCondUsers.map((user) => {
                return new ObjectId(user.id);
              })
            );
    
            if (index === 0) break;
            index--;
          }
    

    在我的辩护中,我正在用三种不同的语言从事 3 个不同的项目,所以我往往会忘记简单的事情......无论如何,如果其他人有类似的问题,你去吧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 2019-10-10
      • 2021-07-02
      • 2020-07-17
      • 2013-01-18
      • 2016-11-11
      相关资源
      最近更新 更多