Prisma ORM+MongoDB:如何按多属性分组文档并整理其余字段
解决方案:使用Prisma的MongoDB聚合管道实现高效分组
由于Prisma的groupBy API对MongoDB的支持有限(仅支持聚合统计类操作,无法将分组内的字段打包为数组),直接调用MongoDB原生的聚合管道是最优的单查询方案——全程在数据库层面完成分组和数据重组,彻底避免应用层拉取全量数据后再映射的低效问题。
核心代码实现
以下是直接在Prisma中使用聚合管道的示例,完全满足你按subject_code+class_code分组、将差异字段打包为schedule数组的需求:
// Express路由示例 app.get('/grouped-events', async (req, res) => { try { const groupedEvents = await prisma.event.aggregate({ _pipeline: [ // 第一步:按subject_code和class_code分组,打包差异字段到schedule数组 { $group: { _id: { subject_code: "$subject_code", class_code: "$class_code" }, schedule: { $push: { week_day: "$week_day", start_time: "$start_time", end_time: "$end_time", // 可添加其他需要的差异字段 location: "$location" } } } }, // 第二步:重组结果格式,把_id中的字段提至顶层,移除冗余的_id { $project: { _id: 0, subject_code: "$_id.subject_code", class_code: "$_id.class_code", schedule: 1 } } ] }); res.json(groupedEvents); } catch (error) { console.error(error); res.status(500).json({ error: '获取分组事件失败' }); } });
关键说明
$group阶段:
- 用
_id指定分组键(subject_code+class_code的组合) - 用
$push将每组内的差异字段(week_day、start_time等)打包为数组
- 用
$project阶段:
- 把
_id中的subject_code和class_code提取为顶层字段,让结果格式更符合业务需求 - 移除
_id字段,避免返回冗余数据
- 把
可选扩展:
- 如果需要先过滤数据,可在
$group之前添加$match阶段(比如{ $match: { status: "active" } }) - 如果需要对
schedule数组排序,可在$group后添加$unwind+$sort+$group的组合操作
- 如果需要先过滤数据,可在
结果格式示例
返回的结果会自动包含所有subject_code+class_code的唯一组合,格式如下:
[ { "subject_code": "CS101", "class_code": "A", "schedule": [ { "week_day": 1, "start_time": "09:00", "end_time": "10:40", "location": "Room 101" }, { "week_day": 3, "start_time": "09:00", "end_time": "10:40", "location": "Room 101" } ] }, { "subject_code": "MA202", "class_code": "B", "schedule": [ { "week_day": 2, "start_time": "14:00", "end_time": "15:40", "location": "Room 202" } ] } ]
内容的提问来源于stack exchange,提问作者Rodrigo Magaldi
相关产品推荐
相关产品推荐

