Mongodb $和运算符无法正常工作

时间:2019-10-05 06:49:25

标签: javascript mongodb mongoose

我有一个基本的社交媒体应用程序,允许用户互相关注。当需要查找某些特定人员的“关注者”时,我会在其“关注者”中查找具有该特定人员ID的用户;

{
          $and: [
            {
              $and: [
                {
                  "following.userId": mongoose.Types.ObjectId(targetId)
                },
                {
                  "following.following": true
                }
              ]
            },
            {
              $or: [{ firstName: firstNameRegex }, { lastName: lastNameRegex }]
            },
            { blockedUsers: { $nin: mongoose.Types.ObjectId(req.userId) } }
          ]
        };

如果用户停止关注某人,则“ following.following”属性将变为false。 当运行此查询时,我得到某个时候跟踪该特定人员的所有人员,而根本没有看到“ following.following”:真正的财产。 “ following.following”不评估“ following.userId”匹配的时间,而是查找整个数组,如果其中一些具有“ following.following” true,则匹配。

Here is the file structure

2 个答案:

答案 0 :(得分:0)

我设法使用$ elemMatch运算符解决了这个问题,

{
          $and: [
            {
              following: {
                $elemMatch: {
                  userId: mongoose.Types.ObjectId(targetId),
                  following: true
                }
              }
            },
            {
              $or: [{ firstName: firstNameRegex }, { lastName: lastNameRegex }]
            },
            { blockedUsers: { $nin: mongoose.Types.ObjectId(req.userId) } }
          ]
        };

答案 1 :(得分:0)

您正在查询嵌入式数组文档,简单的$和查询对您的使用方式没有帮助。

基本上,我们要匹配数组中单个嵌入文档中的多个字段。

所以让我们考虑这个例子:

  

为简单起见,我根据自己的理解添加了一些字段,并且   考虑到您遇到$和查询问题,我将   因此,假设rest查询不会改变并且可以工作。

db.followers.find().pretty()
{
    "_id" : ObjectId("5d984403d933b7b079038ca9"),
    "userId" : "1",
    "followers" : [
        {
            "fId" : "4",
            "following" : true
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : false
        }
    ]
}
{
    "_id" : ObjectId("5d984422d933b7b079038caa"),
    "userId" : "2",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : false
        },
        {
            "fId" : "4",
            "following" : false
        }
    ]
}
{
    "_id" : ObjectId("5d984432d933b7b079038cab"),
    "userId" : "3",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "4",
            "following" : true
        }
    ]
}
{
    "_id" : ObjectId("5d984446d933b7b079038cac"),
    "userId" : "4",
    "followers" : [
        {
            "fId" : "1",
            "following" : false
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : true
        }
    ]
}

ANS 1:

db.followers.find({followers:{ "fId": "1", "following": true  }}).pretty()
{
    "_id" : ObjectId("5d984422d933b7b079038caa"),
    "userId" : "2",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : false
        },
        {
            "fId" : "4",
            "following" : false
        }
    ]
}
{
    "_id" : ObjectId("5d984432d933b7b079038cab"),
    "userId" : "3",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "4",
            "following" : true
        }
    ]
}

请注意在查询中如何使用followers数组。 ref enter link description here

对于您而言,我们可以像这样修改您的查询:

   {
      $and: [                // by default it's $and only, you don't have to mention explicitly
        {
          $and: [            // you can even remove this $and
            "following":
            {
              "userId": mongoose.Types.ObjectId(targetId),
              "following": true
            }
          ]
        },
        {
          $or: [{ firstName: firstNameRegex }, { lastName: lastNameRegex }]
        },
        { blockedUsers: { $nin: mongoose.Types.ObjectId(req.userId) } }
      ]
 }

ANS 2:

您可以使用$elemMatch

$ elemMatch用于查询数组中单个文档的多个字段。

db.followers.find({followers: {$elemMatch: { "fId": "1", "following": true  }}}).pretty()
{
    "_id" : ObjectId("5d984422d933b7b079038caa"),
    "userId" : "2",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : false
        },
        {
            "fId" : "4",
            "following" : false
        }
    ]
}
{
    "_id" : ObjectId("5d984432d933b7b079038cab"),
    "userId" : "3",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "4",
            "following" : true
        }
    ]
}

查询您将是:

{
      $and: [
        {
            "following":
                {$elemMatch: {
                    "userId": mongoose.Types.ObjectId(targetId),
                    "following": true
                }
             }
        },
        {
          $or: [{ firstName: firstNameRegex }, { lastName: lastNameRegex }]
        },
        { blockedUsers: { $nin: mongoose.Types.ObjectId(req.userId) } }
      ]
}

但是会出错(请参见下面的查询):

db.followers.find({"followers.fId": "1", "followers.following": true  }).pretty()
{
    "_id" : ObjectId("5d984422d933b7b079038caa"),
    "userId" : "2",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : false
        },
        {
            "fId" : "4",
            "following" : false
        }
    ]
}
{
    "_id" : ObjectId("5d984432d933b7b079038cab"),
    "userId" : "3",
    "followers" : [
        {
            "fId" : "1",
            "following" : true
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "4",
            "following" : true
        }
    ]
}
{
    "_id" : ObjectId("5d984446d933b7b079038cac"),
    "userId" : "4",
    "followers" : [
        {
            "fId" : "1",
            "following" : false
        },
        {
            "fId" : "2",
            "following" : true
        },
        {
            "fId" : "3",
            "following" : true
        }
    ]
}
  

注意

     

要仅查看匹配的文档,可以使用

db.followers.find({followers: {$elemMatch: { "fId": "1", "following": true  }}},{"followers.$": 1}).pretty()


db.followers.find({followers: {$elemMatch: { "fId": "1", "following": true  }}},{"followers.$": 1}).pretty()