Reputation: 527
The idea here is to return an array of documents of the users' followers with the information if this user is a friend of that follower or not.
So far I have:
db.getCollection('users').aggregate([
{ $match: { _id: ObjectId("588877d82523b4395039910a") } },
{ $lookup: {
from: 'users',
localField: 'followers',
foreignField: '_id',
as: 's_followers'
}
},
{
$project: {
"s_followers._id": 1,
"s_followers.isFriend": {
$in: ["s_followers.id",
{ $setIntersection: ["$friends", "$followers"] }
]}
}
}
])
But the "s_followers.id" used in the $in operator doesn't seem to retrieve the _id information from the follower, so it always returns false.
When I use a ObjectId directly, I got the result I want:
"s_followers.isFriend": {
$in: [ObjectId("588877d82523b4395039910a"),
{ $setIntersection: ["$friends", "$followers"] }
]}
But I really need this ID to be a reference to the follower _id.
Expected result would be something like:
{
"_id" : ObjectId("588877d82523b4395039910a"),
"s_followers" : [
{
"_id" : ObjectId("5888687e56be8f172844d96f"),
"isFriend" : true
},
{
"_id" : ObjectId("5888ca27d79b8b03949a6e8c"),
"isFriend" : false
}
]
}
Thanks for your help!
UPD: A different approach (maybe easier), would be to use the ID of the user that I have (the one used on $match), but I would still need to get the reference for the follower's follower array
db.getCollection('users').aggregate([
{ $match: { _id: ObjectId("588877d82523b4395039910a") } },
{ $lookup: {
from: 'users',
localField: 'followers',
foreignField: '_id',
as: 's_followers'
}
}, {
$project: {
"firstName": 1,
"s_followers._id": 1,
"s_followers.firstName": 1,
"s_followers.followers": 1,
"s_followers.isFriend": { $in: [ObjectId("588877d82523b4395039910a"), "$s_followers.followers"] }
}
}
])
UPD2: The user data structure (the part that matters)
{
followers: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
friends: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
}
Upvotes: 2
Views: 58
Reputation: 527
FOR VERSION 3.4.0+
Ok, just got it, I'll post here the code and my understanding of it:
db.getCollection('users').aggregate([
{ $match: { _id: ObjectId("588877d82523b4395039910a") } },
{ $lookup: {
from: 'users',
localField: 'followers',
foreignField: '_id',
as: 's_followers'
}
}, {
$project: {
"firstName": 1,
"s_followers._id": 1,
"s_followers.firstName": 1,
"s_followers.followers": 1,
}
}, {
$unwind: "$s_followers"
}, {
$project: {
"firstName": "$s_followers.firstName",
"isFriend": { $in: [ObjectId("588877d82523b4395039910a"), "$s_followers.followers"] }
}
}
])
My understanding of it:
Upvotes: 1
Reputation: 16805
In my example use followers friends
list to check current user
is friend or not. as {$arrayElemAt:["$s_followers.friends",0]}
if want to find in followers
then can use "$s_followers.followers"
You can try it.
db.getCollection('user').aggregate([
{ $match: { _id: ObjectId("5714d190e6128b7e7f8d9008") } },
{$unwind:"$followers"},
{ $lookup: {
from: 'user',
localField: 'followers',
foreignField: '_id',
as: 's_followers'
}
},
{$project:{
firstName:1,
s_followers:{$arrayElemAt:["$s_followers",0]},
isFriend:{$cond:[{
$anyElementTrue:{
$map: {"input": {$arrayElemAt:["$s_followers.friends",0]},
"as": "el",
"in": { "$eq": [ "$$el", "$_id" ] }
}
}
},true,false]}
}
},
{$group:{
_id:"$_id",
s_followers:{$push:{_id:"$s_followers._id",isFriend:"$isFriend"}}
}
}
])
Upvotes: 0