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

在Express/Node.js中使用Reduce方法统计MongoDB月度FORM条目数量

解决方案

原有代码错误点

  • 你错误将查询得到的数组first_api通过JSON.stringify转为了字符串,reduce是数组专属方法,无法在字符串上调用,这是触发报错的核心原因
  • reduce回调函数中返回了未定义的变量result,应该返回累加器对象r
  • 未做月份数字到英文名称的转换,无法匹配你需要的输出格式

修改后的api.js路由代码

const express = require('express');
const router = express.Router();
const Api = require('../models/Api');

// 月份英文名称映射,和Date.getMonth()返回的0-11索引一一对应
const monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];

router.get('/', async (req, res) => {
    try{
        // 注意:如果需要统计所有月份的FORM数据,请删除createdDate的时间范围过滤条件
        const first_api = await Api.find({ 
            code: 'FORM', 
            // 如需全量统计删除下面两行即可
            createdDate: {
                $gte: new Date(Date.UTC(2021, 4, 16)), 
                $lte: new Date(Date.UTC(2021, 4, 31))
            }
        }, ['createdDate']).sort( { createdDate: -1 });

        // 统计逻辑
        const countByMonth = first_api.reduce((acc, { createdDate }) => {
            // 取日期对应的月份英文名称
            const monthKey = monthNames[new Date(createdDate).getMonth()];
            // 累加计数
            acc[monthKey] = (acc[monthKey] || 0) + 1;
            return acc;
        }, {});

        // 按要求把统计对象放到数组中返回
        res.json([countByMonth]);
        console.log(countByMonth);
    }catch (err) {
        res.json({message: err});
    }
});

代码说明

  1. 提前定义月份英文映射数组,直接通过Date.getMonth()返回的索引即可拿到对应的月份英文名称
  2. 直接对Mongoose返回的文档数组调用reduce做统计,不需要额外做JSON序列化/反序列化处理
  3. 最终返回的结果用数组包裹,完全匹配你要求的输出格式
  4. 如果需要统计所有历史数据的月份分布,删除查询条件中的createdDate时间范围过滤即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 03:06:04