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

如何从MongoDB含多层对象数组的集合中获取指定数据?

解决MongoDB多层嵌套数组过滤问题

你需要过滤两层嵌套数组的数据,findOne中的$elemMatch仅支持单层数组匹配,因此需要通过聚合管道来实现需求。以下是两种对应你期望结果的实现方式:

方式一:直接获取目标子文档

通过$unwind展开数组,逐层筛选后提取目标字段:

db.collection.aggregate([
  // 第一步:筛选PlayerUid=1的文档
  { $match: { PlayerUid: 1 } },
  // 展开ListData数组,便于后续筛选
  { $unwind: "$ListData" },
  // 筛选ListData中Id=101的项
  { $match: { "ListData.Id": 101 } },
  // 展开ListInfo数组
  { $unwind: "$ListData.ListInfo" },
  // 筛选ListInfo中Uid=5的项
  { $match: { "ListData.ListInfo.Uid": 5 } },
  // 仅保留需要的字段,去除默认_id
  { $project: { _id: 0, Uid: "$ListData.ListInfo.Uid", content: "$ListData.ListInfo.content" } }
])

执行结果:

{ "Uid" : 5, "content" : "Which I wanted" }

方式二:保留外层结构的过滤结果

使用$filter和$map操作符,在保留外层文档结构的同时,仅保留符合条件的嵌套数组项:

db.collection.aggregate([
  { $match: { PlayerUid: 1 } },
  {
    $project: {
      _id: 0,
      PlayerUid: 1,
      ListData: {
        // 过滤ListData数组,只保留Id=101的元素
        $filter: {
          input: "$ListData",
          cond: { $eq: ["$$this.Id", 101] }
        }
      }
    }
  },
  {
    $project: {
      PlayerUid: 1,
      ListData: {
        $map: {
          input: "$ListData",
          as: "listItem",
          in: {
            Id: "$$listItem.Id",
            // 过滤ListInfo数组,只保留Uid=5的元素
            ListInfo: {
              $filter: {
                input: "$$listItem.ListInfo",
                cond: { $eq: ["$$this.Uid", 5] }
              }
            }
          }
        }
      }
    }
  }
])

执行结果(注:你示例中的Id存在笔误,正确应为101而非100):

{
  "PlayerUid" : 1,
  "ListData" : [
    {
      "Id" : 101,
      "ListInfo" : [ { "Uid" : 5, "content" : "Which I wanted" } ]
    }
  ]
}

注意事项

  • 上述操作支持MongoDB 3.2及以上版本;
  • 若集合数据量较大,务必先通过$match缩小处理范围,避免全表扫描;
  • findOne无法直接处理多层嵌套数组的精准过滤,聚合管道是此类场景的标准解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:20:27