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

如何在Mongoose中返回符合条件的嵌套数组匹配元素?

MongoDB 查询:按指定code过滤数组元素并保留文档结构

原始文档

{
    "_id": "63aadd124fabe6c7f5cb3af5",
    "url": "https://github.com",
    "sender": "username@gmail.com",
    "recipients": [
        {
            "email": "recipient1@gmail.com",
            "code": "XY231",
            "position": 54
        },
        {
            "email": "recipient1@gmail.com",
            "code": "XY231",
            "position": 48
        },
        {
            "email": "recipient2@gmail.com",
            "code": "AB124",
            "position": 114
        }
    ],
    "properties": [
        {
            "page": 0,
            "recipient": {
              "email": "recipient1@gmail.com",
              "code": "XY231"
            }
        },
        {
            "page": 2,
            "recipient": {
              "email": "recipient2@gmail.com",
              "code": "AB124"
            }
        }
    ],
    "createdAt": "2023-01-11T16:02:56.126Z",
    "updatedAt": "2023-01-14T09:49:41.962Z",
    "__v": 0
}

查询需求

基于 recipients.code: XY231 过滤文档,要求:

  • 保留原文档整体结构
  • recipients 数组仅保留匹配 code: XY231 的元素
  • properties 数组仅保留其嵌套 recipient.code 为 XY231 的元素
  • 若 recipients 无匹配元素,返回空数组或null

预期返回结果:

{
    "_id": "63aadd124fabe6c7f5cb3af5",
    "url": "https://github.com",
    "sender": "username@gmail.com",
    "recipients": [
        {
            "email": "recipient1@gmail.com",
            "code": "XY231",
            "position": 54
        },
        {
            "email": "recipient1@gmail.com",
            "code": "XY231",
            "position": 48
        }
    ],
    "properties": [
        {
            "page": 0,
            "recipient": {
              "email": "recipient1@gmail.com",
              "code": "XY231"
            }
        }
    ],
    "createdAt": "2023-01-11T16:02:56.126Z",
    "updatedAt": "2023-01-14T09:49:41.962Z",
    "__v": 0
}

尝试过的方法及问题

使用 $unwind 和 $project 组合查询,但仅返回单个匹配元素,文档结构被破坏,返回结果如下:

{
    "_id": "63aadd124fabe6c7f5cb3af5",
    "url": "https://github.com",
    "sender": "username@gmail.com",
    "recipients": {
            "email": "recipient1@gmail.com",
            "code": "XY231"
     },
    "properties": {
            "page": 0,
            "recipient": {
              "email": "recipient1@gmail.com",
              "code": "XY231"
            },
            {
            "email": "recipient1@gmail.com",
            "code": "XY231"
        }
     },
    "createdAt": "2023-01-11T16:02:56.126Z",
    "updatedAt": "2023-01-14T09:49:41.962Z",
    "__v": 0
}

解决方案

使用 MongoDB 聚合框架的 $match + $project + $filter 组合实现需求:

db.collection.aggregate([
  // 先筛选包含目标code的文档,减少后续处理量
  {
    $match: {
      "recipients.code": "XY231"
    }
  },
  // 过滤数组元素并保留原文档字段
  {
    $project: {
      url: 1,
      sender: 1,
      createdAt: 1,
      updatedAt: 1,
      __v: 1,
      // 过滤recipients数组,保留code匹配的元素
      recipients: {
        $filter: {
          input: "$recipients",
          cond: { $eq: ["$$this.code", "XY231"] }
        }
      },
      // 过滤properties数组,保留嵌套recipient.code匹配的元素
      properties: {
        $filter: {
          input: "$properties",
          cond: { $eq: ["$$this.recipient.code", "XY231"] }
        }
      }
    }
  },
  // 可选:排除过滤后recipients为空的文档,不需要可删除此阶段
  {
    $match: {
      $expr: { $ne: ["$recipients", []] }
    }
  }
])

说明

  • $match 阶段先筛选出符合条件的文档,避免对无关文档进行处理
  • $filter 操作符精准过滤数组元素,保留原数组结构,不会像 $unwind 那样展开数组
  • 最后一个 $match 用于过滤掉无匹配元素的文档,若需保留这类文档(返回空数组)可直接移除该阶段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:55:16