MongoDB聚合查询:找出双向通信最频繁的用户交互对
找出MongoDB中通信最频繁的用户对
嘿,这个需求我熟!咱们得先把数据格式统一,再合并双向通信的统计,最后排序找出最活跃的用户对。下面一步步来拆解:
第一步:统一发送方与接收方字段
你给出的文档有两种格式:一种用from表示发送方,另一种用user表示发送方,都是用to表示接收方。首先得把它们标准化成统一的sender(发送方)和recipient(接收方)字段,方便后续处理:
{ $addFields: { sender: { $ifNull: ["$from", "$user"] }, // 优先取from,没有则取user recipient: "$to" } }
第二步:生成标准化的用户对
要把A→B和B→A视为同一对用户,我们可以把发送方和接收方组成数组,再按字符串顺序排序——这样不管谁发谁,得到的数组都是唯一的标识:
{ $addFields: { userPair: { $sortArray: { input: ["$sender", "$recipient"], sortBy: 1 } } } }
比如Tom→Jack和Jack→Tom都会被转换成["Jack", "Tom"],完美统一。
第三步:分组统计通信总量
现在按标准化后的userPair分组,统计每组的邮件总数:
{ $group: { _id: "$userPair", totalMessages: { $sum: 1 } } }
第四步:排序并筛选结果
按通信总量降序排序,这样最频繁的用户对会排在最前面。如果只需要Top1,再加个$limit:1即可:
{ $sort: { totalMessages: -1 } }, { $limit: 1 } // 可选,只取最频繁的那一对
完整聚合命令
把上面的步骤组合起来,完整的聚合管道如下:
db.yourCollectionName.aggregate([ // 统一发送方和接收方 { $addFields: { sender: { $ifNull: ["$from", "$user"] }, recipient: "$to" } }, // 可选:排除给自己发邮件的情况 { $match: { $expr: { $ne: ["$sender", "$recipient"] } } }, // 生成标准化用户对 { $addFields: { userPair: { $sortArray: { input: ["$sender", "$recipient"], sortBy: 1 } } } }, // 分组统计 { $group: { _id: "$userPair", totalMessages: { $sum: 1 } } }, // 排序取Top { $sort: { totalMessages: -1 } }, { $limit: 1 } ])
测试你的示例数据
用你给出的文档测试,最终会得到结果:
{ "_id" : [ "Jack", "Tom" ], "totalMessages" : 3 }
对应Jack和Tom之间的3次通信(Jack→Tom两次,Tom→Jack一次),完全符合需求。
内容的提问来源于stack exchange,提问作者Алексей Гуринович
相关产品推荐
相关产品推荐

