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

如何在MongoDB中查询子数组含指定ID且孙文档匹配条件的文档

解决MongoDB嵌套数组匹配及提取目标孙文档的问题

原查询失效的原因及修复

你写的查询返回0条结果,核心是两个问题:

  1. 错误的类型转换:集合里kids._id是普通字符串(如'Test1'),不是MongoDB的ObjectId类型,所以不能用ObjectId('Test1'),直接写字符串值即可。
  2. 数组条件未关联:原查询的两个条件是分别匹配kids数组中的任意元素,可能出现一个kid匹配_id: 'Test1',另一个kid匹配grandkids.name: 'Bloh',但没有同一个kid同时满足两个条件的情况。必须用$elemMatch把两个条件绑定到同一个kids元素上。

修复后的查询可以正确找到Parent2文档:

{
  "kids": {
    "$elemMatch": {
      "_id": "Test1",
      "grandkids.name": "Bloh"
    }
  }
}

仅返回匹配的孙文档

如果要直接输出符合条件的孙文档(而非整个父文档),用聚合管道实现,推荐两种方式:

方式1:展开数组逐步筛选

适合需要明确处理每一层数组的场景:

db.collection.aggregate([
  // 先筛选出包含目标kid的父文档
  {
    $match: {
      "kids": {
        "$elemMatch": {
          "_id": "Test1",
          "grandkids.name": "Bloh"
        }
      }
    }
  },
  // 展开kids数组
  { $unwind: "$kids" },
  // 筛选出符合条件的kid
  {
    $match: {
      "kids._id": "Test1",
      "kids.grandkids.name": "Bloh"
    }
  },
  // 展开grandkids数组
  { $unwind: "$kids.grandkids" },
  // 筛选出目标孙文档
  {
    $match: {
      "kids.grandkids.name": "Bloh"
    }
  },
  // 只保留孙文档的字段
  {
    $project: {
      _id: 0,
      name: "$kids.grandkids.name"
    }
  }
])

方式2:用数组过滤直接提取(更简洁)

通过$filter直接定位目标元素,无需多次展开数组:

db.collection.aggregate([
  // 先筛选出符合条件的父文档
  {
    $match: {
      "kids": {
        "$elemMatch": {
          "_id": "Test1",
          "grandkids.name": "Bloh"
        }
      }
    }
  },
  // 过滤出匹配的kid
  {
    $addFields: {
      matchedKid: {
        $first: {
          $filter: {
            input: "$kids",
            cond: {
              $and: [
                { $eq: ["$$this._id", "Test1"] },
                { $in: ["Bloh", "$$this.grandkids.name"] }
              ]
            }
          }
        }
      }
    }
  },
  // 过滤出匹配的孙文档
  {
    $addFields: {
      matchedGrandkid: {
        $first: {
          $filter: {
            input: "$matchedKid.grandkids",
            cond: { $eq: ["$$this.name", "Bloh"] }
          }
        }
      }
    }
  },
  // 将孙文档作为根文档返回
  { $replaceRoot: { newRoot: "$matchedGrandkid" } },
  // 可选:移除自动生成的_id
  { $project: { _id: 0 } }
])

两种方式最终都会返回:

{ "name": "Bloh" }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:18:12