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

MongoDB聚合:如何合并多层嵌套数组为单个数组置于文档根节点

问题原因

直接通过路径$tasks.assigned.solutions访问多层嵌套数组时,MongoDB会逐层保留数组维度:第一层对应根节点的tasks数组维度,第二层对应每个task下的assigned数组维度,第三层才是每个assigned节点下的solutions数组本身。你当前使用的$map操作仅做原样元素返回,没有做任何数组展开扁平化处理,因此最终得到三层嵌套数组。

修复方案

使用$reduce配合$concatArrays逐层展开两层嵌套数组,最终合并得到一维的solutions数组,代码如下:

const order = this.orderModel
  .aggregate([
    { $match: { _id: orderId, student: studentId } },
    {
      $addFields: {
        solutions: {
          // 第一层遍历:展开tasks数组维度
          $reduce: {
            input: '$tasks',
            initialValue: [],
            in: {
              $concatArrays: [
                '$$value',
                {
                  // 第二层遍历:展开assigned数组维度,合并所有solutions
                  $reduce: {
                    input: '$$this.assigned',
                    initialValue: [],
                    in: { $concatArrays: ['$$value', '$$this.solutions'] }
                  }
                }
              ]
            }
          }
        }
      }
    }
  ])
  .exec();
  • 上述写法兼容MongoDB 4.0及以上所有版本,执行后会把所有层级下的solutions元素合并为根节点下的一维数组。
  • 如果需要对solutions做条件筛选,只需要把上述$reduce的返回结果作为$filter的输入,在cond字段中写筛选规则即可,示例:
solutions: {
  $filter: {
    input: {
      // 粘贴上面两层$reduce的完整逻辑作为输入
      $reduce: {
        input: '$tasks',
        initialValue: [],
        in: {
          $concatArrays: [
            '$$value',
            {
              $reduce: {
                input: '$$this.assigned',
                initialValue: [],
                in: { $concatArrays: ['$$value', '$$this.solutions'] }
              }
            }
          ]
        }
      }
    },
    as: 'item',
    // 示例筛选规则:name字段包含'有效'关键词
    cond: { $regexMatch: { input: '$$item.name', regex: '有效' } }
  }
}

注意:不要尝试用多层$unwind做扁平化,会大幅增加聚合阶段的内存开销,数据量较大时性能远低于$reduce+$concatArrays的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:27:18