我想要的结果是检查常见的ID以及他们在朋友之间的数量。一个是关闭的朋友计数,另一个是正常的朋友计数。
这里的数据是我的朋友列表,用户就是我。
async function uinfo(data, user){
const arr = []
for (const i of data) {
await Profile.aggregate([{"$match": {"_id": {"$in": [user, i._id]}}}, {"$unwind": "$list.closedFriends"}, {"$group": {_id: "$list.closedFriends.id", count: {$sum: 1}}}, {$match: {count: 2}}, {$project: {_id: 1}}], function(err, result){
if(result.length >= 1){
i.cfcount = result.length
}
else{
i.cfcount = 0
}
})
await Profile.aggregate([{"$match": {"_id": {"$in": [user, i._id]}}}, {"$unwind": "$list.friends"}, {"$group": {_id: "$list.friends.id", count: {$sum: 1}}}, {$match: {count: 2}}, {$project: {_id: 1}}], function(err, result1){
if(result1.length >= 1){
i.fcount = result1.length
}
else{
i.fcount = 0
}
})
arr.push(i)
}
console.log(arr)
return await Promise.all(arr)
}
通过执行两个单独的查询,我得到了正确的结果,但我想结合这两个查询。
上面的一个问题是,result1的输出没有给出最后一次提取(或匹配)的承诺输出。
修改: -
{ "_id" : 1, "friends" : [2,3,4], "closedFriends":[5,6,7] }
{ "_id" : 2, "friends" : [ 1,3,5 ], "closedFriends" : [4,6,7] }
在上面的数据库中,1和2之间的常见朋友是3,closedFriends是6和7.所需的输出是cfcount是2,fcount是1和ids。
EDIT2: -
{ "_id" : 1, "friends" : [{id:1, name:'john', score:0}, {id:2, name:'john', score:0}, {id:3, name:'john', score:0}], "closedFriends":[{id:8, name:'john', score:0}, {id:4, name:'john', score:0}, {id:5, name:'john', score:0}] }
{ "_id" : 2, "friends" : [{id:2, name:'john', score:0}, {id:7, name:'john', score:0}, {id:3, name:'john', score:0} ], "closedFriends" : [{id:1, name:'john', score:0}, {id:9, name:'john', score:0}, {id:8, name:'john', score:0}] }
除此之外,我想要包括已提交的姓名'和'得分'在汇总输出中。
答案 0 :(得分:1)
聚合框架可以替换您的所有Javascript计算(用于循环计数),从而消除您所做的 o(2n)聚合计算,只消除一个 O(1)
function uinfo(data, user){
let mainUser = db.Profile.findOne({_id: user});
let userIds = Array.from(data, user => user.id);
return Profile.aggregate([
{$match: {'_id': {$in: userIds}}},
{
$project: {
'_id' : 1,
'fcount': {
$size: {
$setIntersection: [
mainUser.friends,
'$friends',
]
}
},
'cfcount': {
$size: {
$setIntersection: [
mainUser.closedFriends,
'$closedFriends',
]
}
}
}
},
])
}