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

MongoDB如何简化嵌套数组标签过滤查询,无需枚举返回字段?

MongoDB查询:自动返回所有字段同时过滤嵌套数组

问题描述

我的数据结构如下:

[
  {
    "item": "journal",
    "qty": 25,
    "status": "A",
    "weekNumber": 1,
    "sortOrder": 1,
    "label": 1,
    "numberOfPossibleDays": 1,
    "editable": 1,
    "selectedDate": 1,
    "deliveryDays": 1,
    "products": [
      {
        "key": "item-one",
        "name": "item one",
        "tags": ["v", "b"]
      },
      {
        "key": "item-two",
        "name": "item-two",
        "tags": ["a", "c", "d"]
      },
      {
        "_id": 3,
        "name": "item-three",
        "tags": ["g"]
      }
    ]
  },
  {
    "item": "notebook",
    "status": "b",
    "qty": 1,
    "weekNumber": 1,
    "sortOrder": 1,
    "label": 1,
    "numberOfPossibleDays": 1,
    "editable": 1,
    "selectedDate": 1,
    "deliveryDays": 1,
    "products": [
      {
        "key": "item-four",
        "name": "item four",
        "tags": ["a", "o"]
      },
      {
        "key": "item-five",
        "name": "item-five",
        "tags": ["s", "a", "b"]
      }
    ]
  }
]

需要查询所有包含标签a的文档,并且返回时过滤掉products数组中包含a的元素,预期结果如下:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "deliveryDays": 1,
    "editable": 1,
    "item": "journal",
    "label": 1,
    "numberOfPossibleDays": 1,
    "products": [
      {
        "key": "item-one",
        "name": "item one",
        "tags": ["v", "b"]
      }
    ],
    "qty": 25,
    "selectedDate": 1,
    "sortOrder": 1,
    "status": "A",
    "weekNumber": 1
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "deliveryDays": 1,
    "editable": 1,
    "item": "notebook",
    "label": 1,
    "numberOfPossibleDays": 1,
    "products": [],
    "qty": 1,
    "selectedDate": 1,
    "sortOrder": 1,
    "status": "b",
    "weekNumber": 1
  }
]

目前使用$filter在投影阶段过滤数组时,必须手动枚举所有需要返回的字段,代码过于冗长,希望找到无需逐个指定字段、自动返回所有字段的方法。

解决方案

使用MongoDB的聚合管道,通过$set(或$addFields)操作符可以保留所有原有字段,仅修改products数组,无需手动枚举其他字段:

db.collection.aggregate([
  // 匹配包含标签'a'的文档
  { $match: { "products.tags": "a" } },
  // 过滤products数组,仅保留不包含标签'a'的元素
  {
    $set: {
      products: {
        $filter: {
          input: "$products",
          cond: { $not: { $in: ["a", "$$this.tags"] } }
        }
      }
    }
  }
])

说明

  • $match阶段:筛选出包含标签a的products的文档,和原查询的匹配条件一致。
  • $set阶段:替换products字段为过滤后的数组,文档中其他所有字段会自动保留,不需要手动列出。如果使用MongoDB 4.2之前的版本,$addFields操作符效果相同(字段存在时会替换,不存在时添加)。
  • $filter的cond条件:使用$not和$in组合,过滤掉包含a标签的products元素,符合预期结果要求。

执行该聚合查询后,会自动返回所有字段,同时products数组仅保留不包含a的元素,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:05:20