You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Алексей Гуринович

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:38:19