如何根据一个特定文档的数组过滤 MongoDB 个文档?
How to filter MongoDB documents based on one specific document's array?
我有一个 collection 这样的:
{
_id: "blabla",
userName: "blablabla",
..
interactedUsers: [
"blabla2"
"some other user's id",
"some other user's id",
]
},
{
_id: "blabla2",
userName: "blablabla2",
..
interactedUsers: [
"some other user's id",
"some other user's id",
]
},
现在,如果我是 "_id: "blabla"
的用户,我想获取除 "blabla2"
之外的所有用户,因为它在我的 "interactedUsers"
数组中。我怎样才能做到这一点?我尝试了很多聚合组合,但无法真正得到想要的结果。
由于您可能不想使用 $facet
,因为它会将您的所有集合合并到一个大文档中,另一种选择是使用 $lookup
.
这允许您将“忽略的”文档添加到所有其他文档,然后从答案中删除包含它的文档。这样做的好处是您的所有文档在整个过程中都是分开的:
db.collection.aggregate([
{
$addFields: {"ignore": "blabla" }
},
{
$lookup: {
from: "collection",
localField: "ignore",
foreignField: "_id",
as: "ignore"
}
},
{
$set: {ignore: {$arrayElemAt: ["$ignore", 0]}}
},
{
$match: {
$expr: {$not: {$in: ["$_id", "$ignore.interactedUsers"]}}
}
},
{
$unset: "ignore"
},
{
$match: {$expr: {$ne: ["$_id", "blabla"]}}
}
])
这是 return 集合中所有 "_id"
而不是 "interactedUsers"
的另一种方法。
db.collection.aggregate([
{ "$match": { "_id": "blabla0" } },
{
"$lookup": {
"from": "collection",
"let": { "notIds": { "$setUnion": [ [ "$_id" ], "$interactedUsers" ] } },
"pipeline": [
{ "$match": { "$expr": { "$not": { "$in": [ "$_id", "$$notIds" ] } } } },
{ "$project": { "_id": 1 } }
],
"as": "strangers"
}
},
{
"$set": {
"strangers": {
"$map": {
"input": "$strangers",
"in": "$$this._id"
}
}
}
}
])
在 mongoplayground.net 上试用。
我有一个 collection 这样的:
{
_id: "blabla",
userName: "blablabla",
..
interactedUsers: [
"blabla2"
"some other user's id",
"some other user's id",
]
},
{
_id: "blabla2",
userName: "blablabla2",
..
interactedUsers: [
"some other user's id",
"some other user's id",
]
},
现在,如果我是 "_id: "blabla"
的用户,我想获取除 "blabla2"
之外的所有用户,因为它在我的 "interactedUsers"
数组中。我怎样才能做到这一点?我尝试了很多聚合组合,但无法真正得到想要的结果。
由于您可能不想使用 $facet
,因为它会将您的所有集合合并到一个大文档中,另一种选择是使用 $lookup
.
这允许您将“忽略的”文档添加到所有其他文档,然后从答案中删除包含它的文档。这样做的好处是您的所有文档在整个过程中都是分开的:
db.collection.aggregate([
{
$addFields: {"ignore": "blabla" }
},
{
$lookup: {
from: "collection",
localField: "ignore",
foreignField: "_id",
as: "ignore"
}
},
{
$set: {ignore: {$arrayElemAt: ["$ignore", 0]}}
},
{
$match: {
$expr: {$not: {$in: ["$_id", "$ignore.interactedUsers"]}}
}
},
{
$unset: "ignore"
},
{
$match: {$expr: {$ne: ["$_id", "blabla"]}}
}
])
这是 return 集合中所有 "_id"
而不是 "interactedUsers"
的另一种方法。
db.collection.aggregate([
{ "$match": { "_id": "blabla0" } },
{
"$lookup": {
"from": "collection",
"let": { "notIds": { "$setUnion": [ [ "$_id" ], "$interactedUsers" ] } },
"pipeline": [
{ "$match": { "$expr": { "$not": { "$in": [ "$_id", "$$notIds" ] } } } },
{ "$project": { "_id": 1 } }
],
"as": "strangers"
}
},
{
"$set": {
"strangers": {
"$map": {
"input": "$strangers",
"in": "$$this._id"
}
}
}
}
])
在 mongoplayground.net 上试用。