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

MongoDB中如何查询嵌套数组数据并返回指定子元素

MongoDB查询问题解决方案

一、解决仅返回符合条件audit元素的问题

你之前的两个查询存在的局限:

  • 第一个查询使用items.$投影,MongoDB的位置操作符$仅会返回数组中第一个匹配查询条件的元素,无法获取所有符合条件的项。
  • 第二个查询直接指定{"items":1},只会返回整个items数组,不会对数组内元素做过滤,因此会返回全部数据。

要正确过滤并返回所有符合条件的audit元素,推荐使用聚合管道,以下是两种可行方案:

方案1:用$filter精准筛选数组元素

在投影阶段通过$filter嵌套筛选符合条件的items和audit:

db.Balances.aggregate([
  // 先匹配包含目标audit的文档
  {
    $match: {
      "items.audit.validTo": { $lte: ISODate("2024-01-20T14:24:57.483Z") }
    }
  },
  // 过滤items中包含符合条件audit的项
  {
    $project: {
      items: {
        $filter: {
          input: "$items",
          as: "item",
          cond: {
            $anyElementTrue: {
              $map: {
                input: "$$item.audit",
                as: "audit",
                in: { $lte: ["$$audit.validTo", ISODate("2024-01-20T14:24:57.483Z")] }
              }
            }
          }
        }
      }
    }
  },
  // 进一步过滤每个item内的audit元素
  {
    $addFields: {
      items: {
        $map: {
          input: "$items",
          as: "item",
          in: {
            id: "$$item.id",
            audit: {
              $filter: {
                input: "$$item.audit",
                as: "audit",
                cond: { $lte: ["$$audit.validTo", ISODate("2024-01-20T14:24:57.483Z")] }
              }
            }
          }
        }
      }
    }
  }
])

方案2:用$unwind拆分数组后匹配重组

通过拆分数组、匹配条件、重新分组的方式还原结构:

db.Balances.aggregate([
  {
    $match: {
      "items.audit.validTo": { $lte: ISODate("2024-01-20T14:24:57.483Z") }
    }
  },
  // 拆分items数组
  { $unwind: "$items" },
  // 拆分items内的audit数组
  { $unwind: "$items.audit" },
  // 匹配符合条件的audit元素
  {
    $match: {
      "items.audit.validTo": { $lte: ISODate("2024-01-20T14:24:57.483Z") }
    }
  },
  // 按item id分组还原audit数组
  {
    $group: {
      _id: { _id: "$_id", itemId: "$items.id" },
      audit: { $push: "$items.audit" }
    }
  },
  // 还原items数组结构
  {
    $group: {
      _id: "$_id._id",
      items: { $push: { id: "$_id.itemId", audit: "$audit" } }
    }
  }
])

二、仅显示audit列表的解决方案

如果希望最终结果只保留符合条件的audit列表,无需items结构,可修改聚合管道直接提取audit元素:

db.Balances.aggregate([
  {
    $match: {
      "items.audit.validTo": { $lte: ISODate("2024-01-20T14:24:57.483Z") }
    }
  },
  { $unwind: "$items" },
  { $unwind: "$items.audit" },
  {
    $match: {
      "items.audit.validTo": { $lte: ISODate("2024-01-20T14:24:57.483Z") }
    }
  },
  // 收集所有符合条件的audit
  {
    $group: {
      _id: null,
      audit: { $push: "$items.audit" }
    }
  },
  // 移除自动生成的_id字段
  { $project: { _id: 0 } }
])

执行后会得到如下结果:

{
  "audit": [
    {
      "validFrom": ISODate("2021-01-20T14:24:57.483Z"),
      "validTo": ISODate("2024-01-20T14:24:57.483Z")
    },
    {
      "validFrom": ISODate("2021-01-19T14:24:57.483Z"),
      "validTo": ISODate("2024-01-19T14:24:57.483Z")
    }
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:05:29