'How to filter MongoDB documents based on one specific document's array?
I have a collection like this:
{
_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",
]
},
Now if i am the user with "_id: "blabla" i want to fetch all users except "blabla2" because its in my "interactedUsers" array. How can i do that? I tried so many aggregation combinations but couldn't really get the wanted result.
Solution 1:[1]
Since you probably don't want to use $facet as it will merge all your collection into one big document, another option is to use $lookup.
This allows you to add the "ignored" document to all other documents and then remove from the answer the ones that contain it. The advantage here is that all your documents are kept separated along the process:
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"]}}
}
])
Solution 2:[2]
Here's another way to return all "_id" in the collection not in "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"
}
}
}
}
])
Try it on mongoplayground.net.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | rickhg12hs |
