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

MongoDB聚合$group后添加ObjectId类型_id字段的实现疑问

MongoDB聚合结果添加ObjectId类型_id字段(源集合无_id场景)

场景背景

现有regions集合文档(示例):

{
  region: "US",
  name: "United State"
},
{
  region: "US",
  name: "United State"
}

执行原聚合命令后得到无_id字段的结果:

db.regions.aggregate([
    {$group: {_id: {region: "$region", name: "$name"}, priority: {$sum: 1}}},
    {$project: { code: "$_id.region", name: "$_id.name", priority: "$priority"}
])

返回结果:

{ "code" : "US", "name" : "United State", "priority" : 2}

需求:生成包含ObjectId类型_id字段的聚合结果,以便用$out输出到新集合,目标格式:

{ "code" : "US", "name" : "United State", "priority" : 2, _id: ObjectId("xxxxxxxxxxx")}

已实现的源集合含_id时的方案(参考@Gibbs提示):

db.collection.aggregate([
  {
    $group: {
      "id": {
        $push: "$_id"
      },
      _id: {
        region: "$region",
        name: "$name"
      },
      priority: { $sum: 1 }
    }
  },
  {
    $project: {
      code: "$_id.region",
      name: "$_id.name",
      priority: "$priority",
      _id: {
        $first: "$id"
      }
    }
  }
])

核心问题

若源集合本身不包含_id字段,如何在聚合结果中添加ObjectId类型的_id字段?

解决方案

利用MongoDB 4.4+版本支持的$function操作符,在聚合的$project阶段生成新的ObjectId:

方案代码示例

db.regions.aggregate([
  {
    $group: {
      _id: { region: "$region", name: "$name" },
      priority: { $sum: 1 }
    }
  },
  {
    $project: {
      code: "$_id.region",
      name: "$_id.name",
      priority: "$priority",
      _id: {
        $function: {
          body: function() { return new ObjectId(); },
          args: [],
          lang: "js"
        }
      }
    }
  },
  { $out: "target_collection" } // 将结果输出到目标集合
])

说明

  1. $function允许在聚合中调用JavaScript函数,这里通过new ObjectId()生成唯一的ObjectId值
  2. 该方法要求MongoDB版本≥4.4;如果是更低版本,可在聚合后通过客户端代码生成ObjectId再插入目标集合
  3. 生成的ObjectId具备MongoDB主键的唯一性特性,适合作为输出集合的_id字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:30:45