La idea aquí es devolver una serie de documentos de los seguidores de los usuarios con la información de si este usuario es amigo de ese seguidor o no.
Hasta ahora tengo:
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"] } ]} } } ])Pero el "s_followers.id" utilizado en el operador $in no parece recuperar la información de _id del seguidor, por lo que siempre devuelve falso.
Cuando uso un ObjectId directamente, obtuve el resultado que quiero:
"s_followers.isFriend": { $in: [ObjectId("588877d82523b4395039910a"), { $setIntersection: ["$friends", "$followers"] } ]}Pero realmente necesito que este ID sea una referencia al _id del seguidor.
El resultado esperado sería algo como:
{ "_id" : ObjectId("588877d82523b4395039910a"), "s_followers" : [ { "_id" : ObjectId("5888687e56be8f172844d96f"), "isFriend" : true }, { "_id" : ObjectId("5888ca27d79b8b03949a6e8c"), "isFriend" : false } ] }¡Gracias por tu ayuda!
UPD: un enfoque diferente (quizás más fácil) sería usar la ID del usuario que tengo (la que se usa en $match), pero aún necesitaría obtener la referencia para la matriz de seguidores del seguidor.
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: La estructura de datos del usuario (la parte que importa)
{ followers: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }], friends: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }], }PARA LA VERSIÓN 3.4.0+
Ok, lo acabo de recibir, publicaré aquí el código y mi comprensión del mismo:
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"] } } } ])Mi comprensión de la misma:
En mi ejemplo, use la lista de followers friends para verificar que el user actual sea amigo o no. como {$arrayElemAt:["$s_followers.friends",0]} si desea encontrar followers , puede usar "$s_followers.followers"
Puedes probarlo.
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"}} } } ])