如何在Mongoose的aggregation聚合的$sort阶段执行计算并排序
Mongoose聚合$sort按动态计算值排序的正确实现
错误原因
原有写法存在两个核心问题:
$sort阶段仅接受「字段名: 排序方向(1为升序/-1为降序)」的键值对结构,不支持直接传入计算表达式- 代码中的
Math.pow、new Date()是在Node.js服务端执行的,无法读取MongoDB中每条文档的date字段值,计算逻辑完全没有作用
正确实现
你需要先通过$addFields(MongoDB 4.2+也可以用$set)阶段提前计算出排序权重字段,再基于该字段排序,完整代码如下:
const test = await Test.aggregate([ // 第一步:计算排序权重字段 { $addFields: { sortWeight: { $divide: [ "$value", // 读取当前文档的value字段 { $pow: [ 1.1, // 计算已过天数:当前时间减文档date字段,毫秒转成天 { $divide: [ { $subtract: [new Date(), "$date"] }, // 可替换为$$NOW取MongoDB服务端统一时间 1000 * 60 * 60 * 24 // 毫秒转天数的换算系数 ] } ] } ] } } }, // 第二步:按权重排序,-1为降序(权重高的在前),1为升序 { $sort: { sortWeight: -1 } }, // 可选:不需要返回权重字段可通过该阶段移除 { $unset: "sortWeight" } ]);
补充说明
- 如果你需要严格按整数天数计算,可以给天数计算部分外层套
$floor(向下取整,不满24小时不算1天)或者$ceil(向上取整,满1小时就算1天) - 替换
new Date()为MongoDB内置变量$$NOW可以避免Node.js服务和MongoDB服务的时间差问题,保证时间计算标准统一
内容的提问来源于stack exchange,提问作者James Lee
相关产品推荐
相关产品推荐

