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

MongoDB聚合中如何将date数组字段拆分为相邻两个独立字段

MongoDB聚合将date数组元素映射为独立命名字段实现方案

根据数组长度是否固定,可选择两种实现方式:

场景1:date数组长度固定

如果所有文档的date数组长度为已知固定值(比如示例中固定为2),直接在$project/$set阶段通过$arrayElemAt按索引取值即可,写法最简单、执行性能最优:

db.yourCollection.aggregate([
  {
    $project: {
      // _id默认会保留,无需额外声明
      date1: { $arrayElemAt: ["$date", 0] }, // 数组第1个元素对应date1,索引从0开始
      date2: { $arrayElemAt: ["$date", 1] }  // 数组第2个元素对应date2
      // 数组长度更长时,按顺序追加dateN,对应数组索引为n-1即可
    }
  }
])

该方式执行后输出结构和需求给出的示例完全一致。

场景2:date数组长度不固定

如果不同文档的date数组长度不一致,需要动态按数组实际长度生成date1/date2/.../dateN字段,可通过$arrayToObject结合$map动态构造字段,无需提前约定数组长度:

db.yourCollection.aggregate([
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          // 保留原文档除date数组外的所有字段(包含_id)
          {
            $arrayToObject: {
              $filter: {
                input: { $objectToArray: "$$ROOT" },
                cond: { $ne: ["$$this.k", "date"] }
              }
            }
          },
          // 按数组顺序动态生成带序号的date字段
          {
            $arrayToObject: {
              $map: {
                input: { $range: [0, { $size: "$date" }] },
                in: {
                  k: { $concat: ["date", { $toString: { $add: ["$$this", 1] } }] },
                  v: { $arrayElemAt: ["$date", "$$this"] }
                }
              }
            }
          }
        ]
      }
    }
  }
])

核心逻辑说明

  • 用$range生成从0到数组长度的连续索引序列
  • 用$map遍历索引,将每个索引对应的日期组装为{k: 字段名, v: 日期值}的键值结构,字段名序号为索引值+1
  • 用$arrayToObject将键值结构转换为正式的文档字段
  • 用$mergeObjects合并原文档保留字段和新生成的date字段,最后通过$replaceRoot输出为最终文档结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:03:29