如何对单个集合的两个嵌套数组聚合,生成共同密友与普通好友统计结果?
完善共同好友统计功能实现
嘿,我来帮你搞定这个统计自己和好友的共同密友、普通好友的需求!先理清楚你的核心目标:针对data里的每个好友,分别算出和你(user)的共同密友数量+ID列表、共同普通好友数量+ID列表对吧?
先看你现有代码的问题:它是批量查询所有好友和你的共同密友,但没法对应到单个好友的统计,而且只处理了密友,没覆盖普通好友。下面是完整的实现方案:
完整异步函数实现
async function uinfo(data, user) { const friendStats = []; // 逐个遍历每个好友,单独计算共同好友数据 for (const friend of data) { const friendId = friend._id; // 🔍 统计共同密友 const commonClosedFriends = await Profile.aggregate([ { $match: { _id: { $in: [user, friendId] } } }, { $unwind: "$list.closedFriends" }, { $group: { _id: "$list.closedFriends.id", count: { $sum: 1 } } }, { $match: { count: 2 } }, { $project: { _id: 1 } } ]); // 🔍 统计共同普通好友(注意:替换成你实际的普通好友字段,比如list.friends) const commonNormalFriends = await Profile.aggregate([ { $match: { _id: { $in: [user, friendId] } } }, { $unwind: "$list.normalFriends" }, { $group: { _id: "$list.normalFriends.id", count: { $sum: 1 } } }, { $match: { count: 2 } }, { $project: { _id: 1 } } ]); // 整理当前好友的统计结果 friendStats.push({ friendId, // 共同密友相关 commonClosedFriendIds: commonClosedFriends.map(item => item._id), commonClosedFriendsCount: commonClosedFriends.length, // 共同普通好友相关 commonNormalFriendIds: commonNormalFriends.map(item => item._id), commonNormalFriendsCount: commonNormalFriends.length }); } return friendStats; }
关键逻辑说明
- 逐个好友统计:用
for...of配合await遍历每个好友,确保每个好友的统计结果能精准对应,避免批量查询的混乱 - 聚合查询逻辑:
$match:筛选出你和当前好友的Profile文档$unwind:展开好友列表数组,把每个好友单独变成一条文档$group:按好友ID分组,统计每个ID出现的次数$match: { count: 2 }:只保留出现2次的ID(也就是你和当前好友都有的好友)$project:只返回好友ID,减少数据量
- 结果整理:把每个好友的共同好友ID列表和数量都整理到结果数组,方便后续使用
注意事项
- 替换普通好友字段:如果你的普通好友不是存在
list.normalFriends,一定要改成你实际的字段名(比如list.friends) - 数据结构要求:确保
Profile集合里的每个文档,list.closedFriends和普通好友字段都是数组类型,且每个数组元素包含id字段(对应好友的_id) - 调用方式:因为是异步函数,调用时要加
await,比如:const myFriends = [/* 你的好友列表数据 */]; const myUserId = "xxx"; const stats = await uinfo(myFriends, myUserId); console.log(stats);
内容的提问来源于stack exchange,提问作者code.mevn
相关产品推荐
相关产品推荐

