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

Mongoose中如何仅获取匹配指定条件的内部数组元素?

问题:Mongoose中过滤数组子文档未生效

在Mongoose中尝试获取匹配特定条件的内部数组记录,但返回所有子记录,仅处理了父节点而非子节点。使用$project聚合函数未达到预期效果,现有数据包含drawings数组,期望仅返回其中assigned_to为6的元素,尝试过aggregate、$match、$project等方法均无效。

原始数据

[
  {
    "_id": {"$oid": "636b9958d6ea5d0cc85d20a6"},
    "project_type": 1,
    "title": "Pariatur Aut repreh",
    "id": 4,
    "drawings": [
      {"id": 1,"assigned_to": 4,"assigned_name": "Desirae Sandoval","assigned_by": 3},
      {"id": 1,"assigned_to": 6,"assigned_name": "Desirae Sandoval","assigned_by": 3}
    ],
    "status": 1,
    "created_at": {"$date": {"$numberLong": "1667995992724"}}
  }
]

期望结果

[
  {
    "_id": {"$oid": "636b9958d6ea5d0cc85d20a6"},
    "project_type": 1,
    "title": "Pariatur Aut repreh",
    "id": 4,
    "drawings": [
      {"id": 1,"assigned_to": 6,"assigned_name": "Desirae Sandoval","assigned_by": 3}
    ],
    "status": 1,
    "created_at": {"$date": {"$numberLong": "1667995992724"}}
  }
]

解决方案

方法1:使用聚合管道的$filter(推荐,支持返回所有匹配的子文档)

通过$filter在$project阶段筛选数组中符合条件的元素,这是最准确的方式:

YourModel.aggregate([
  // 可选:先匹配父文档(比如按id筛选,缩小处理范围)
  { $match: { id: 4 } },
  {
    $project: {
      project_type: 1,
      title: 1,
      id: 1,
      drawings: {
        $filter: {
          input: "$drawings",
          as: "item",
          cond: { $eq: ["$$item.assigned_to", 6] }
        }
      },
      status: 1,
      created_at: 1
    }
  }
])

$filter会遍历drawings数组,仅保留满足cond条件(assigned_to等于6)的元素,最终返回的drawings数组只包含符合要求的子文档。

方法2:使用find配合$elemMatch(仅返回第一个匹配的子文档)

如果只需要数组中第一个符合条件的子文档,可以用$elemMatch:

YourModel.find(
  { "drawings.assigned_to": 6 },
  { 
    project_type: 1,
    title: 1,
    id: 1,
    drawings: { $elemMatch: { assigned_to: 6 } },
    status: 1,
    created_at: 1
  }
)

注意:该方法仅返回drawings数组中第一个匹配条件的元素,若有多个符合条件的子文档,建议使用方法1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:25:37