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

如何在MongoDB中查询文档不同层级下的同名字段值

MongoDB不限嵌套层级查询指定字段所有值的实现方案

完全可以实现该需求,你可以通过MongoDB聚合管道结合自定义递归函数的方式,提取任意嵌套层级下指定字段的所有值,不需要提前知道字段的嵌套位置。

针对你给出的文档结构,参考聚合查询语句如下:

db.collection.aggregate([
  {
    $addFields: {
      allIps: {
        $function: {
          body: function(doc) {
            const ips = [];
            // 递归遍历所有层级的对象和数组
            const extractIp = (target) => {
              if (Array.isArray(target)) {
                target.forEach(item => extractIp(item));
                return;
              }
              if (typeof target === 'object' && target !== null) {
                Object.keys(target).forEach(key => {
                  if (key === 'ip') {
                    ips.push(target[key]);
                  } else {
                    extractIp(target[key]);
                  }
                })
              }
            }
            extractIp(doc);
            return ips;
          },
          args: ["$$ROOT"],
          lang: "js"
        }
      }
    }
  },
  // 以下两个阶段为可选,用于将集合内所有文档的ip合并为全局列表
  { $unwind: "$allIps" },
  // 若不需要去重,将$addToSet改为$push即可
  { $group: { _id: null, globalIps: { $addToSet: "$allIps" } } }
])

方案说明

  • 自定义函数会递归遍历当前完整文档($$ROOT代表当前文档的全部内容)的所有层级,包括嵌套对象、嵌套数组内部的字段
  • 只要匹配到键名为ip的字段,就会将对应值存入结果数组,不受嵌套位置和层级限制
  • 如果仅需要每个文档自身包含的所有ip列表,删除聚合管道最后的$unwind和$group阶段即可

注意事项

  • 该方案要求MongoDB版本 >= 4.4,仅该版本及以上支持$function运算符
  • 若使用的MongoDB版本更低,可以在应用服务层读取文档后,复用上面的extractIp递归逻辑完成字段提取
  • 若你明确知道所有ip字段可能出现的嵌套路径,也可以通过$project + $concatArrays手动合并所有路径的ip值,该方案查询性能更高,但扩展性差,新增嵌套路径时需要修改查询语句

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:45:04