Вы можете использовать ниже агрегации:
db.UserDetails.aggregate(
{
$lookup: {
from: "UserProducts",
localField: "UID",
foreignField: "UID",
as: "userProduct"
}
},
{ $unwind: "$userProduct" },
{
"$project": { "_id" : 0, "userProduct.UPID" : 1 }
},
{
$group: {
_id: null,
userProductUPIDs: { $addToSet: "$userProduct.UPID" }
}
},
{
$lookup: {
from: "Groups",
pipeline: [
{ $unwind: "$members.regularStudent" },
{ $project: { _id: 0, value: "$members.regularStudent" } }
],
as: "UPID"
}
},
{
$addFields: {
UPID: {
$map: {
input: "$UPID",
as: "x",
in: "$$x.value"
}
}
}
},
{
$project: {
result: {
$setDifference: [ "$userProductUPIDs", "$UPID" ]
}
}
}
)
По сути, целью является получение одного документа с двумя массивами для выполнения $ setDifference . У вас уже есть правильная часть (просто нужно добавить $ group ), и вам нужно $ lookup с пользовательским конвейером , чтобы получить все данные из Groups
в одну коллекцию. Выходы:
{ "_id" : null, "result" : [ "100" ] }
РЕДАКТИРОВАТЬ: для запуска $lookup
с настраиваемым конвейером вам потребуется MongoDB 3.6 или новее. В качестве альтернативы вам нужно запустить два агрегата, а затем сравнить оба результата в логике вашего приложения:
var queryResult = db.UserDetails.aggregate(
{
$lookup: {
from: "UserProducts",
localField: "UID",
foreignField: "UID",
as: "userProduct"
}
},
{ $unwind: "$userProduct" },
{
"$project": { "_id" : 0, "userProduct.UPID" : 1 }
},
{
$group: {
_id: null,
userProductUPIDs: { $addToSet: "$userProduct.UPID" }
}
}
) // returns [ "100", "200" ]
let userProductUPIDs = queryResult.toArray()[0].userProductUPIDs;
db.Groups.aggregate([
{
$unwind: "$members.regularStudent"
},
{
$group: {
_id: null,
UPIDs: { $addToSet: "$members.regularStudent" }
}
},
{
$project: {
members: {
$setDifference: [ userProductUPIDs , "$UPIDs" ]
},
_id : 0
}
}
])