MongoDB如何实现字符串数组字段符合预期的自定义降序排序?
问题原因
MongoDB 对数组字段执行排序时的默认规则为:
- 升序排序:取数组内的最小元素参与比较,最小元素相同则依次对比后续元素,长度更短的数组优先级更高
- 降序排序:取数组内的最大元素参与比较
你的三个文档的customs数组最大元素分别为222、333、333,因此默认降序会把最大元素为333的两个文档排在最前面,和你预期的「升序结果反转」的逻辑不符。
解决方案
方案1:应用层直接处理(最简单,适合数据量小的场景)
先按升序查询得到符合你逻辑的结果,直接在代码里把结果数组反转即可:
const ascResult = await db.find('user').sort({customs: 1}).toArray() const descResult = ascResult.reverse()
方案2:MongoDB 聚合管道生成倒序序号(通用,无额外限制)
通过聚合先按正确的升序排序,再给文档加倒序序号后重新排序,得到你要的降序结果:
db.user.aggregate([ // 按你验证过正确的升序规则排序 { $sort: { customs: 1 } }, // 把排序后的文档聚合为数组 { $group: { _id: null, docs: { $push: "$$ROOT" } } }, // 展开数组同时生成升序序号 { $unwind: { path: "$docs", includeArrayIndex: "asc_rank" } }, // 按升序序号倒排,得到升序反转的结果 { $sort: { asc_rank: -1 } }, // 还原原始文档结构 { $replaceRoot: { newRoot: "$docs" } } ])
方案3:拼接数组为字符串作为排序键(性能更高,适合数组元素格式固定的场景)
如果你的customs数组存储时本身就是升序排列,且元素为固定格式的字符串,可以直接把数组拼接为字符串作为排序键,再对这个键降序:
db.user.aggregate([ // 拼接数组为排序用的字符串 { $addFields: { sort_key: { $reduce: { input: "$customs", initialValue: "", in: { $concat: ["$$value", "|", "$$this"] } } } } }, // 按自定义排序键降序 { $sort: { sort_key: -1 } }, // 移除临时的排序键字段 { $unset: "sort_key" } ])
内容的提问来源于stack exchange,提问作者jiqing liu
相关产品推荐
相关产品推荐

