我有一个基本的社交媒体应用程序,允许用户互相关注。当需要查找某些特定人员的“关注者”时,我会在其“关注者”中查找具有该特定人员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,则匹配。
答案 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()