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

如何编写MongoDB查询,筛选含标签a的嵌套元素并保留符合条件子项?

MongoDB筛选文档并过滤嵌套数组元素

给定数据集:

[
  {
    "item": "journal",
    "qty": 25,
    "status": "A",
    "products": [
        {
            "key": "item-one",
            "name": "item one",
            "tags": ["a", "b"]
        },
        {
            "key": "item-two",
            "name": "item-two",
            "tags": ["a", "c", "d"]
        },
        {
            "_id": 3,
            "name": "item-three",
            "tags": ["g"]
        }
    ]
  },
  {
    "item": "notebook",
    "qty": 50,
    "status": "b",
    "products": [
        {
            "key": "item-four",
            "name": "item four",
            "tags": ["a", "o"]
        },
        {
            "key": "item-five",
            "name": "item-five",
            "tags": ["s", "a", "d"]
        }
    ]
  }
]

需求:筛选出所有包含标签a的文档(即products数组中至少有一个子文档的tags包含a),同时每个文档的products数组仅保留tags包含a的子文档,预期结果如下:

[
  {
    "item": "journal",
    "qty": 25,
    "status": "A",
    "products": [
        {
            "key": "item-one",
            "name": "item one",
            "tags": ["a", "b"]
        },
        {
            "key": "item-two",
            "name": "item-two",
            "tags": ["a", "c", "d"]
        }
    ]
  },
  {
    "item": "notebook",
    "qty": 50,
    "status": "b",
    "products": [
        {
            "key": "item-four",
            "name": "item four",
            "tags": ["a", "o"]
        },
        {
            "key": "item-five",
            "name": "item-five",
            "tags": ["s", "a", "d"]
        }
    ]
  }
]

解决方法:使用MongoDB聚合管道

通过$match结合$filter操作符即可实现需求,以下是两种可选方案:

方案1:显式指定保留字段($project)

db.collection.aggregate([
  // 筛选出products中存在tags包含"a"的父文档
  {
    $match: {
      "products.tags": "a"
    }
  },
  // 过滤products数组,仅保留符合条件的子文档
  {
    $project: {
      item: 1,
      qty: 1,
      status: 1,
      products: {
        $filter: {
          input: "$products",
          as: "product",
          cond: { $in: ["a", "$$product.tags"] }
        }
      }
    }
  }
])

方案2:自动保留所有原有字段($addFields)

如果父文档字段较多,不想逐个列举,可使用$addFields替换$project,自动保留所有字段并覆盖过滤后的products数组:

db.collection.aggregate([
  {
    $match: {
      "products.tags": "a"
    }
  },
  {
    $addFields: {
      products: {
        $filter: {
          input: "$products",
          as: "product",
          cond: { $in: ["a", "$$product.tags"] }
        }
      }
    }
  }
])

代码说明

  1. $match阶段:快速过滤出符合条件的父文档,减少后续处理的数据量;
  2. $filter操作:遍历products数组,通过$in判断子文档的tags是否包含a,仅保留符合条件的子元素。

执行上述任意一段聚合查询,均可得到需求中的预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:55:29