如何在Mongoose中对字符串格式的time时间字段实现正确排序?
时间字符串排序解决方案
你不需要修改数据库原有字段类型,可根据业务场景选择以下两种方案实现正确排序:
方案1:数据库聚合查询实现(推荐)
适合数据量大、有分页需求的场景,直接在数据库层面完成排序,不影响分页逻辑正确性:
const users = await UserModel.aggregate([ // 新增临时排序字段,将时间字符串转为当天0点开始的总分钟数 { $addFields: { timeSortValue: { $let: { vars: { period: { $substr: ["$time", -2, 2] }, timePart: { $substr: ["$time", 0, { $subtract: [{ $strLenCP: "$time" }, 3] }] }, }, in: { $let: { vars: { hour: { $toInt: { $arrayElemAt: [{ $split: ["$$timePart", ":"] }, 0] } }, minute: { $toInt: { $arrayElemAt: [{ $split: ["$$timePart", ":"] }, 1] } } }, in: { $add: [ { $multiply: [ { $cond: [ { $eq: ["$$period", "AM"] }, { $cond: [{ $eq: ["$$hour", 12] }, 0, "$$hour"] }, { $cond: [{ $eq: ["$$hour", 12] }, 12, { $add: ["$$hour", 12] }] } ]}, 60 ]}, "$$minute" ] } } } } } } }, // 按转换后的数值升序排序 { $sort: { timeSortValue: 1 } }, // 移除临时字段,返回数据结构和原查询一致 { $unset: "timeSortValue" } ])
方案2:应用层本地排序实现
适合数据量小于1000条、无分页需求的场景,代码实现更简洁:
// 先查询全量数据 const users = await UserModel.find({}); // 本地完成时间排序 users.sort((a, b) => { const timeToMinutes = (timeStr) => { const [time, period] = timeStr.split(' '); let [hour, minute] = time.split(':').map(Number); // 转换为24小时制对应的总分钟数 if (period === 'AM' && hour === 12) hour = 0; if (period === 'PM' && hour !== 12) hour += 12; return hour * 60 + minute; } return timeToMinutes(a.time) - timeToMinutes(b.time); })
内容的提问来源于stack exchange,提问作者ffx292
相关产品推荐
相关产品推荐

