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

如何通过MongoDB聚合提取含嵌套字段的点分隔全量键名列表

解决方案

你可以直接使用MongoDB 4.4+版本支持的$function聚合运算符实现需求,该语法在Atlas免费版完全可用,不需要调用map-reduce能力,你已经写好的JS递归逻辑稍作优化即可直接嵌入聚合管道运行:

完整可运行聚合代码

db.customers.aggregate([
  // 单文档维度提取所有嵌套键
  {
    $project: {
      keys: {
        $function: {
          body: function(obj) {
            const keys = [];
            const idRegex = new RegExp('_id.*');
            // 递归提取深度嵌套键
            function getDeepKeys(currentObj, parentKey = '') {
              for (const key in currentObj) {
                // 过滤所有_id相关字段
                if (idRegex.test(key)) continue;
                // 拼接带点运算符的全字段名
                const fullKey = parentKey ? `${parentKey}.${key}` : key;
                keys.push(fullKey);
                // 仅处理非null、非数组类型的嵌套对象,避免生成冗余错误键
                if (typeof currentObj[key] === 'object' && currentObj[key] !== null && !Array.isArray(currentObj[key])) {
                  getDeepKeys(currentObj[key], fullKey);
                }
              }
            }
            getDeepKeys(obj);
            return keys;
          },
          args: ["$$ROOT"],
          lang: "js"
        }
      }
    }
  },
  // 汇总所有文档的键
  {
    $group: {
      _id: null,
      allKeys: { $addToSet: "$keys" }
    }
  },
  // 扁平化数组+去重得到最终结果
  {
    $project: {
      _id: 0,
      finalKeys: {
        $reduce: {
          input: "$allKeys",
          initialValue: [],
          in: { $setUnion: ["$$value", "$$this"] }
        }
      }
    }
  }
]).toArray()[0].finalKeys

测试输出

针对你给出的示例文档,运行后输出和预期完全一致:

[
  'name',
  'address',
  'documentType',
  'personalDetails',       
  'personalDetails.gender',
  'personalDetails.age',
  'personalDetails.position'
]

如果需要处理数组类型字段内部的嵌套文档键,只需要在递归逻辑中增加数组判断、遍历数组元素提取键即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:27:03