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

如何从嵌套文档提取键值对并忽略数组对象(批量高效处理)

MongoDB 批量提取post对象中非数组/非对象键值对方案

需求说明

在post集合中批量处理文档:以post_id为键,从post对象里仅提取非数组、非对象类型的键值对,要求实现高性能批量处理。

示例文档

{
   "_id":"1001",
   "post":{
      "country_name":"India",
      "state_name":"Maharashtra",
      "city_name":"Mumbai",
      "duration":"10",
      "country":[
         {
            "name":"india"   
         }
      ],
      "site":[
         {
            "site_no":"101",
            "code":"Taj",
            "name":"santacruz"
         }
      ]
   },
   "post_id":"abcd123"
}

{
   "_id":"1002",
   "post":{
      "country_name":"India",
      "state_name":"Karnataka",
      "city_name":"Bangalore",
      "duration":"20",
      "country":[
         {
            "name":"india"   
         }
      ],
      "site":[
         {
            "site_no":"201",
            "code":"COLES",
            "name":"Coles Park"
         }
      ]
   },
   "post_id":"abcd234"
}

预期结果

{
  "abcd123": {
    "country_name": "India",
    "state_name": "Maharashtra",
    "city_name": "Mumbai",
    "duration": "10"
  },
  "abcd234": {
    "country_name": "India",
    "state_name": "Karnataka",
    "city_name": "Bangalore",
    "duration": "20"
  }
}

高性能批量处理方案

使用MongoDB聚合管道实现,全程在数据库端执行,避免客户端-服务器间多次数据传输,性能远优于循环处理单个文档:

db.post.aggregate([
  // 将post对象转换为键值对数组,保留post_id
  {
    $project: {
      post_id: 1,
      post_kv: { $objectToArray: "$post" }
    }
  },
  // 过滤出value既非数组也非对象的键值对
  {
    $project: {
      post_id: 1,
      filtered_post: {
        $filter: {
          input: "$post_kv",
          cond: {
            $and: [
              { $ne: [{ $type: "$$this.v" }, "array"] },
              { $ne: [{ $type: "$$this.v" }, "object"] }
            ]
          }
        }
      }
    }
  },
  // 将过滤后的键值对数组转回对象
  {
    $project: {
      post_id: 1,
      result: { $arrayToObject: "$filtered_post" }
    }
  },
  // 聚合所有文档,生成以post_id为键的最终对象
  {
    $group: {
      _id: null,
      final: { $mergeObjects: { $arrayToObject: [[{ k: "$post_id", v: "$result" }]] } }
    }
  },
  // 输出最终结果结构
  {
    $replaceRoot: { newRoot: "$final" }
  }
])

方案说明

  1. $objectToArray:把post对象拆解为[{k: 键名, v: 键值}]格式的数组,方便后续过滤。
  2. $filter:通过$type判断值的类型,只保留非数组、非对象的项。
  3. $arrayToObject:将过滤后的键值对数组重新转换为对象。
  4. $group + $mergeObjects:把所有文档的结果合并成一个以post_id为键的整体对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:45:31