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

如何转换MongoDB嵌套对象数组中的日期字符串并查询当月文档

问题原因
  • 嵌套数组路径访问错误:sections和fields都是数组结构,不能直接使用$sections.field[0].value这类路径访问嵌套值,且不能假设name=Date的字段固定在数组首位,必须按字段名匹配取值。
  • 条件判断逻辑错误:$sections.field.value返回的是所有字段value组成的数组,直接与字符串Date判等永远不成立,无法正确识别日期字段。
正确实现方案

首先提取嵌套数组中name=Date对应的值,转换为日期类型后再做月份范围匹配,完整实现代码如下:

const startOfMonth = moment(payload.forPeriod).startOf("month").toDate();
const endOfMonth = moment(payload.forPeriod).endOf("month").toDate();

const existingReports = await Report.aggregate([
  // 提取日期字段并转换为日期类型
  {
    $addFields: {
      documentDate: {
        $reduce: {
          input: "$sections",
          initialValue: null,
          in: {
            $cond: {
              if: { $ne: ["$$value", null] },
              then: "$$value",
              else: {
                $let: {
                  vars: {
                    // 过滤出name为Date的字段
                    dateField: {
                      $arrayElemAt: [
                        {
                          $filter: {
                            input: "$$this.fields",
                            cond: { $eq: ["$$this.name", "Date"] }
                          }
                        },
                        0
                      ]
                    }
                  },
                  in: {
                    $cond: {
                      if: { $ne: ["$$dateField", null] },
                      // 日期字符串转日期类型
                      then: { $dateFromString: { dateString: "$$dateField.value" } },
                      else: null
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  // 匹配指定月份范围内的文档
  {
    $match: {
      documentDate: {
        $gte: startOfMonth,
        $lt: endOfMonth
      }
    }
  }
])

如果确认每个文档的sections数组只有1个元素,且name=Date的字段固定在fields数组首位,可以使用简化写法:

const existingReports = await Report.aggregate([
  {
    $addFields: {
      documentDate: {
        $dateFromString: {
          dateString: "$sections.0.fields.0.value"
        }
      }
    }
  },
  {
    $match: {
      documentDate: {
        $gte: moment(payload.forPeriod).startOf("month").toDate(),
        $lt: moment(payload.forPeriod).endOf("month").toDate()
      }
    }
  }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:24:03