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

MongoDB查询:拆分key首段生成region集合并添加引用ID

处理MongoDB区域数据拆分与关联需求

需求说明

现有MongoDB集合中存在_id为"officeLocation"的文档,其data数组内的对象key字段为多段格式(例如"APAC - ANZ")。需要完成两项操作:

  • 利用正则表达式拆分key的首段内容,生成唯一区域数据存入名为region的新集合
  • 为原officeLocation文档的data数组中每个对象添加对应区域的referenceId引用

原数据示例

{
  "_id": "officeLocation",
  "data": [
    {
      "_id": ObjectId("60d21b4667d0d8992e610c85"),
      "key": "APAC - ANZ",
      "value": "APAC - ANZ"
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c86"),
      "key": "APAC - Japan",
      "value": "APAC - Japan"
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c87"),
      "key": "EMEA - CE - Benelux - Brussels",
      "value": "EMEA - CE - Benelux - Brussels"
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c88"),
      "key": "EMEA - CE - Benelux - London",
      "value": "EMEA - CE - Benelux - London"
    }
  ]
}

预期结果

region集合数据

{
  "_id": ObjectId("60d21b4667d0d8992e610c89"),
  "key": "APAC",
  "value": "APAC"
},
{
  "_id": ObjectId("60d21b4667d0d8992e610c8a"),
  "key": "EMEA",
  "value": "EMEA"
}

更新后的原集合数据

{
  "_id": "officeLocation",
  "data": [
    {
      "_id": ObjectId("60d21b4667d0d8992e610c85"),
      "key": "APAC - ANZ",
      "value": "APAC - ANZ",
      "referenceId": ObjectId("60d21b4667d0d8992e610c89")
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c86"),
      "key": "APAC - Japan",
      "value": "APAC - Japan",
      "referenceId": ObjectId("60d21b4667d0d8992e610c89")
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c87"),
      "key": "EMEA - CE - Benelux - Brussels",
      "value": "EMEA - CE - Benelux - Brussels",
      "referenceId": ObjectId("60d21b4667d0d8992e610c8a")
    },
    {
      "_id": ObjectId("60d21b4667d0d8992e610c88"),
      "key": "EMEA - CE - Benelux - London",
      "value": "EMEA - CE - Benelux - London",
      "referenceId": ObjectId("60d21b4667d0d8992e610c8a")
    }
  ]
}

解决方案

步骤1:提取唯一区域并创建region集合

使用聚合管道拆分data数组,提取key的首段区域,去重后写入region集合:

db.your_collection_name.aggregate([
  // 筛选目标文档
  { $match: { _id: "officeLocation" } },
  // 拆分data数组为单个文档
  { $unwind: "$data" },
  // 提取key的首段区域(匹配第一个" - "之前的内容)
  {
    $project: {
      region: {
        $regexExtract: {
          input: "$data.key",
          regex: "^([^-]+)",
          captureGroup: 1
        }
      }
    }
  },
  // 去除首尾空格
  {
    $project: {
      region: { $trim: { input: "$region" } }
    }
  },
  // 按区域分组去重
  { $group: { _id: "$region" } },
  // 构造region集合的文档结构
  {
    $project: {
      _id: 0,
      key: "$_id",
      value: "$_id"
    }
  },
  // 将结果写入region集合(若集合已存在会覆盖,可用$merge替代)
  { $out: "region" }
])

若需保留region集合原有数据,将最后一步的$out替换为$merge: { into: "region", on: "key", whenMatched: "keepExisting" }

步骤2:更新原文档,添加referenceId关联

使用聚合更新操作,关联region集合获取区域ID,更新原文档的data数组:

db.your_collection_name.updateOne(
  { _id: "officeLocation" },
  [
    // 关联region集合,获取区域与_id的映射
    {
      $lookup: {
        from: "region",
        let: { data: "$data" },
        pipeline: [
          {
            $project: {
              key: 1,
              regionId: "$_id"
            }
          }
        ],
        as: "regionMap"
      }
    },
    // 将regionMap转换为对象,方便后续匹配
    {
      $addFields: {
        regionMap: {
          $arrayToObject: {
            $map: {
              input: "$regionMap",
              as: "item",
              in: { k: "$$item.key", v: "$$item.regionId" }
            }
          }
        }
      }
    },
    // 更新data数组,添加referenceId
    {
      $addFields: {
        data: {
          $map: {
            input: "$data",
            as: "item",
            in: {
              $mergeObjects: [
                "$$item",
                {
                  referenceId: {
                    $getField: {
                      field: {
                        $trim: {
                          input: { $regexExtract: { input: "$$item.key", regex: "^([^-]+)", captureGroup: 1 } }
                        }
                      },
                      input: "$regionMap"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    },
    // 移除临时的regionMap字段
    { $unset: "regionMap" }
  ]
)

注意事项

  • 替换命令中的your_collection_name为实际的集合名称
  • 确保MongoDB版本支持$regexExtract(MongoDB 4.4+),若版本较低可使用$split替代:$arrayElemAt: [{$split: ["$data.key", " - "]}, 0]
  • 执行$out前确认region集合无重要数据,或使用$merge避免覆盖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:06:00