Mongoose排序中,空数组(长度0)为何被视为最大元素?
按数组长度排序时空数组前置的原因及解决方法
问题原因
你直接用sort({ items: 1 })对数组字段排序,本质上是让MongoDB按数组的字典序比较,而非数组长度。在字典序规则里,空数组[]属于最小的元素,所以升序排序(1代表升序)会把所有items为空的文档排在最前面,完全不符合你按长度从多到少排序的需求。
正确实现方式
要实现按items数组长度取前5个最多的集合,必须先计算数组的长度,再基于长度排序,推荐用MongoDB的聚合管道来实现:
const collections = await Collection.aggregate([ // 新增字段存储items数组的长度 { $addFields: { itemsCount: { $size: "$items" } } }, // 按数组长度降序排序,长度越大越靠前 { $sort: { itemsCount: -1 } }, // 只取前5个文档 { $limit: 5 }, // 如果需要关联查询关联的文档,添加对应的$lookup { $lookup: { from: "items", localField: "items", foreignField: "_id", as: "items" } }, { $lookup: { from: "users", localField: "author", foreignField: "_id", as: "author" } }, { $lookup: { from: "topics", localField: "topic", foreignField: "_id", as: "topic" } } ]);
如果你的MongoDB版本在4.4及以上,也可以直接在find的排序逻辑中使用$size,不需要额外新增字段:
const collections = await Collection.find({}) .sort({ $expr: { $size: "$items" } }, -1) .limit(5) .populate("author topic items");
核心逻辑就是:必须通过$size操作符获取数组的实际长度,再基于长度排序,而不是直接对数组字段本身排序。
内容的提问来源于stack exchange,提问作者Yusuf Isakov
相关产品推荐
相关产品推荐

