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

MongoDB聚合中能否利用$sortBy结合字段实现收发方双向配对的分组统计?

如何用MongoDB聚合实现双向配对的分组统计

没问题!完全可以通过MongoDB聚合结合排序相关操作实现这个需求——你提到的$sortBy应该是指MongoDB 5.0+引入的$sortArray操作符,用它来处理双向配对的统一标识非常直观。下面是完整的实现方案:

核心思路

把每个文档的sender和receiver转换成有序的用户对:不管是A→B还是B→A,排序后都会得到相同的[A, B]组合,这样就能把双向配对视为同一分组,再基于这个组合统计总数。

完整聚合管道代码

db.yourCollection.aggregate([
  // 第一步:将sender和receiver转为数组并排序,生成统一的用户对标识
  {
    $addFields: {
      sortedUsers: {
        $sortArray: {
          input: ["$sender", "$receiver"],
          sortBy: 1 // 按字符串升序排序,确保小的在前大的在后
        }
      }
    }
  },
  // 第二步:基于排序后的用户对分组,统计文档数量
  {
    $group: {
      _id: {
        user1: { $arrayElemAt: ["$sortedUsers", 0] },
        user2: { $arrayElemAt: ["$sortedUsers", 1] }
      },
      total: { $sum: 1 }
    }
  },
  // 可选:按总数降序排序,让结果更清晰
  {
    $sort: { total: -1 }
  }
])

代码细节解释

  • $sortArray的作用:它会把sender和receiver组成的数组按指定规则排序,比如B→A会被转换成["A", "B"],和A→B的排序结果完全一致,这就实现了双向配对的统一分组键。
  • 分组统计:用排序后的数组元素作为_id的字段,再用$sum:1统计每组的文档总数。

兼容旧版本MongoDB(5.0以下)

如果你的MongoDB版本低于5.0,没有$sortArray,可以用$cond手动比较字段大小来生成有序用户对:

db.yourCollection.aggregate([
  {
    $addFields: {
      user1: { $cond: [{ $lt: ["$sender", "$receiver"] }, "$sender", "$receiver"] },
      user2: { $cond: [{ $lt: ["$sender", "$receiver"] }, "$receiver", "$sender"] }
    }
  },
  {
    $group: {
      _id: { user1: "$user1", user2: "$user2" },
      total: { $sum: 1 }
    }
  }
])

验证结果

用你提供的示例数据运行上述管道,会得到完全符合预期的输出:

[
  { "_id": { "user1": "A", "user2": "B"}, "total": 2 },
  { "_id": { "user1": "A", "user2": "C"}, "total": 1 },
  { "_id": { "user1": "B", "user2": "C"}, "total": 1 }
]

内容的提问来源于stack exchange,提问作者Aji Aneesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:57:38