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

MongoDB聚合中能否拼接两个DBRef?及交易数据统计需求

嘿,我来帮你搞定这个MongoDB聚合统计的问题,顺便解答你关于DBRef拼接的疑问~

一、完成聚合统计的完整语句

要统计唯一买家数、卖家数,以及买家+卖家的唯一组合数,我们可以通过一次聚合操作完成,具体语句如下:

db.getCollection('transactions').aggregate([
  // 提取买家、卖家的ID,并生成买卖组合标识
  {
    $addFields: {
      buyerId: "$buyer.$id",
      sellerId: "$seller.$id",
      // 将两个ID转成字符串后拼接成唯一组合键
      buyerSellerPair: {
        $concat: [
          { $toString: "$buyer.$id" },
          "|",
          { $toString: "$seller.$id" }
        ]
      }
    }
  },
  // 分组收集所有唯一的买家、卖家和组合
  {
    $group: {
      _id: null,
      uniqueBuyers: { $addToSet: "$buyerId" },
      uniqueSellers: { $addToSet: "$sellerId" },
      uniquePairs: { $addToSet: "$buyerSellerPair" }
    }
  },
  // 计算各类唯一值的数量
  {
    $project: {
      _id: 0,
      uniqueBuyerCount: { $size: "$uniqueBuyers" },
      uniqueSellerCount: { $size: "$uniqueSellers" },
      uniquePairCount: { $size: "$uniquePairs" }
    }
  }
])

语句说明:

  • $addFields阶段:先从DBRef中提取$id字段(直接用整个DBRef对象做去重的话,会包含$ref字段,而我们只需要ID的唯一性),同时用$toString把ObjectId转成字符串,再通过$concat拼接成唯一的买卖组合键。
  • $group阶段:以_id: null进行全局分组,用$addToSet收集所有不重复的买家ID、卖家ID和组合键。
  • $project阶段:用$size计算每个集合的长度,得到我们需要的统计数。

另外,如果你觉得字符串拼接麻烦,也可以用数组来表示买卖组合,这样不需要转字符串,同样能识别唯一组合:

// 修改$addFields里的组合键生成方式
buyerSellerPair: ["$buyer.$id", "$seller.$id"]

这种方式下,只有当买家ID和卖家ID完全相同时,才会被视为同一个组合,统计结果是准确的。

二、关于MongoDB聚合中用$concat拼接DBRef的问题

直接对整个DBRef对象使用$concat是不行的——因为$concat只能接收字符串类型的参数,而DBRef是一个包含$ref和$id的嵌套对象。

但我们可以先提取DBRef中的$id字段(ObjectId类型),通过$toString将其转换为字符串后,再使用$concat进行拼接,就像上面聚合语句里的做法。这样就能实现两个DBRef对应ID的拼接啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:28:42