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

MongoDB如何筛选对象数组中status为Pending的嵌套文档

解决MongoDB嵌套数组元素筛选问题

针对你遇到的场景:需要返回用户文档,但仅保留todos数组中status为"Pending"的元素,而非返回包含匹配项的完整用户文档,以下是可行方案:

示例文档

{
  "_id": ObjectId("123"),
  "name": "Alice",
  "todos": [
    {"task": "Buy milk", "status": "Pending"},
    {"task": "Finish report", "status": "Completed"},
    {"task": "Call mom", "status": "Pending"}
  ]
}

期望返回结果

{
  "_id": ObjectId("123"),
  "name": "Alice",
  "todos": [
    {"task": "Buy milk", "status": "Pending"},
    {"task": "Call mom", "status": "Pending"}
  ]
}

正确解决方案:聚合管道+$filter操作符

这是最精准灵活的方式,能过滤数组中所有符合条件的元素:

db.users.aggregate([
  // 先筛选出至少包含一个Pending待办的用户(可选,减少后续处理数据量)
  { $match: { "todos.status": "Pending" } },
  // 替换todos数组,仅保留status为Pending的元素
  {
    $addFields: {
      todos: {
        $filter: {
          input: "$todos", // 指定待过滤的数组
          cond: { $eq: ["$$this.status", "Pending"] } // 过滤条件,$$this代表数组当前遍历元素
        }
      }
    }
  }
])

替代方案:用$project指定返回字段

若需明确控制返回的字段列表,可替换$addFields为$project:

db.users.aggregate([
  { $match: { "todos.status": "Pending" } },
  {
    $project: {
      name: 1, // 保留name字段
      todos: {
        $filter: {
          input: "$todos",
          cond: { $eq: ["$$this.status", "Pending"] }
        }
      }
    }
  }
])

为什么你之前的方法无效?

  • 直接使用db.users.find({"todos.status": "Pending"}):仅会返回包含至少一个Pending待办的用户文档,但不会过滤数组内不符合条件的元素。
  • 使用find搭配$elemMatch投影:比如db.users.find({"todos.status": "Pending"}, {todos: {$elemMatch: {status: "Pending"}}}),仅会返回数组中第一个匹配的元素,而非所有符合条件的项。

内容的提问来源于stack exchange,提问作者Itti'Z Wallet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:23:31