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

MongoDB find()查询如何过滤文档数组内的指定元素

MongoDB 过滤嵌套数组元素实现方案

普通find()的基础投影语法不支持自定义条件过滤嵌套数组内的元素,可根据你使用的MongoDB版本选择对应实现方式:

  • MongoDB 4.4及以上版本:可直接在find()中使用聚合投影运算符实现
  • 所有版本通用:通过aggregate()聚合管道实现

方式1:find() 直接实现(4.4+版本支持)

查询语句如下,第一个参数是文档级别的匹配条件,无特殊筛选需求可留空对象,第二个参数使用$filter运算符完成数组元素过滤:

db.your_collection_name.find(
  {}, // 此处可填写文档级别的筛选条件,例如 { name: "name" }
  {
    arr: {
      $filter: {
        input: "$arr",
        cond: {
          $not: [
            {
              $and: [
                // 条件1:内嵌arr数组长度为1
                { $eq: [{ $size: "$$this.arr" }, 1] },
                // 条件2:内嵌arr的唯一元素值为"abc"
                { $eq: [{ $arrayElemAt: ["$$this.arr", 0] }, "abc"] }
              ]
            }
          ]
        }
      }
    },
    // 声明需要返回的其他顶层字段
    name: 1,
    field1: 1,
    field2: 1
  }
)

逻辑说明:$filter会遍历外层arr数组的每一个元素,通过$not排除同时满足「内嵌arr长度为1、唯一元素是"abc"」的元素,剩余元素会被保留在返回结果中,和你给出的预期输出完全一致。

方式2:aggregate() 聚合管道实现(全版本兼容)

如果你的MongoDB版本低于4.4,可使用聚合管道实现,过滤逻辑和上述方式完全一致:

db.your_collection_name.aggregate([
  // 文档筛选阶段,无特殊需求可省略
  // { $match: { /* 文档级筛选条件 */ } },
  {
    $project: {
      arr: {
        $filter: {
          input: "$arr",
          cond: {
            $not: [
              {
                $and: [
                  { $eq: [{ $size: "$$this.arr" }, 1] },
                  { $eq: [{ $arrayElemAt: ["$$this.arr", 0] }, "abc"] }
                ]
              }
            ]
          }
        }
      },
      name: 1,
      field1: 1,
      field2: 1
    }
  }
])

优化:无需手动枚举所有顶层字段

如果你的集合文档顶层字段很多,不想逐个在投影中声明,可以使用$replaceRoot+$mergeObjects自动保留所有原字段,仅替换过滤后的arr数组,示例:

db.your_collection_name.aggregate([
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$$ROOT",
          {
            arr: {
              $filter: {
                input: "$arr",
                cond: {
                  $not: [
                    {
                      $and: [
                        { $eq: [{ $size: "$$this.arr" }, 1] },
                        { $eq: [{ $arrayElemAt: ["$$this.arr", 0] }, "abc"] }
                      ]
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
])

注意:该写法仅适用于聚合管道,无法在find()的投影参数中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:15:48