如何修改Next.js API实现按发布日期过滤后按年月统计各学院论文数量
如何修改Next.js API实现按发布日期过滤后按年月统计各学院论文数量
我来帮你调整这段Next.js API代码,实现按年月分组后,统计每个学院在对应年月的论文数量。先理清楚你的需求:原来的接口返回每个年月的总论文数,现在要改成每个年月下返回各学院的具体计数,比如2025年6月CEIS有1篇、SHS有2篇这样的结构。
咱们一步步来改:
1. 核心修改思路
- 把原来
dataPerMonth里的count从单一数字,改成学院名称到数量的映射对象 - 遍历论文时,不再直接累加总计数,而是找到对应学院的字段去累加
- 修复原代码中未使用
college查询参数的问题(你原代码里获取了这个参数,但没在数据库查询条件里用上) - 调整最终返回的数据结构,匹配你想要的格式
2. 修改后的完整代码
import { startOfYear, endOfYear } from 'date-fns'; import { NextRequest, NextResponse } from 'next/server'; import { db } from '@/lib/db'; // 假设你的db导入路径是这个 import type { Paper } from '@/types'; // 假设你的Paper类型定义正确 export async function GET(req: NextRequest) { try { const { searchParams } = new URL(req.url); const year_start = searchParams.get('year_start'); const year_end = searchParams.get('year_end'); const college = searchParams.get('college'); // 处理日期范围 const startOfyearData = year_start ? startOfYear(new Date(year_start)) : null; const endOfyearData = year_end ? endOfYear(new Date(year_end)) : (year_start ? endOfYear(new Date(year_start)) : null); // 查询数据库:补上college参数的过滤逻辑 const papers = await db.publish_Papers.findMany({ where: { AND: [ startOfyearData ? { publication_date: { gte: startOfyearData } } : {}, endOfyearData ? { publication_date: { lte: endOfyearData } } : {}, // 新增:如果传了college参数,只查询该学院的论文 college ? { User: { college } } : {} ] }, include: { User: { select: { college: true } } } }) as Paper[]; // 初始化年月数据结构:count改为学院-数量的映射对象 const dataPerMonth: Record<string, { year: number; month: number; count: Record<string, number> }> = {}; const startYear = year_start ? parseInt(year_start) : new Date().getFullYear(); const endYear = year_end ? parseInt(year_end) : startYear; for (let year = startYear; year <= endYear; year++) { for (let month = 1; month <= 12; month++) { const key = `${year}-${month}`; dataPerMonth[key] = { year, month, count: {} // 这里从0改成空对象,用来存学院的计数 }; } } // 遍历论文,统计各学院的数量 papers.forEach(paper => { const date = new Date(paper.publication_date); const year = date.getUTCFullYear(); const month = date.getUTCMonth() + 1; const key = `${year}-${month}`; const currentCollege = paper.User?.college; if (!currentCollege) return; // 如果没有学院信息,跳过这条数据 if (dataPerMonth[key]) { // 该学院已存在就+1,不存在就初始化为1 dataPerMonth[key].count[currentCollege] = (dataPerMonth[key].count[currentCollege] || 0) + 1; } else { // 极端情况:如果年月不在初始化的范围内(比如过滤逻辑漏了),直接新建 dataPerMonth[key] = { year, month, count: { [currentCollege]: 1 } }; } }); // 排序并转换为带月份名称的结构 const monthCounts = Object.values(dataPerMonth).sort((a, b) => { if (a.year !== b.year) return a.year - b.year; return a.month - b.month; }); const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const monthCountsWithNames = monthCounts.map(item => { return { year: item.year, month: monthNames[item.month - 1], count: item.count // 直接返回学院计数的对象 }; }); return NextResponse.json({ monthCountsWithNames }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ error: 'Failed to load data' }, { status: 500 }); } }
3. 关键修改点说明
- 数据结构调整:把
dataPerMonth里的count从0改成空对象,用来存储学院名: 数量的键值对 - 统计逻辑修改:遍历论文时,拿到当前论文的学院,动态更新对应年月下该学院的计数
- 修复查询参数:原代码里获取了
college参数但没用到,现在加到数据库查询的where条件里,如果你不需要按学院过滤,可以删掉这一行 - 返回结构优化:去掉了原代码里多余的
college字段,直接返回count对象,和你想要的输出格式完全匹配
4. 最终输出示例
调用接口后,返回的结构会变成你想要的样子:
{ "monthCountsWithNames": [ // ...其他年月 { "year": 2025, "month": "June", "count": { "CEIS": 1, "SHS": 2 } }, { "year": 2019, "month": "June", "count": { "SHS": 1 } } // ...其他年月 ] }
这样就完全满足你的需求啦,按发布日期过滤后,按年月分组统计各学院的论文数量~
内容来源于stack exchange
相关产品推荐
相关产品推荐

