Mongoose聚合管道中$sort在populate阶段前失效的原因与解决
问题描述与解决方案
作者Schema定义
{ name: String, birthDate: Date, otherAuthorRatings: { type: [ { author: { type: mongoose.Schema.Types.ObjectId, ref: "Author", }, rating: { type: Number, }, }, ], } }
聚合需求与遇到的问题
使用聚合管道的$unwind、$lookup、$group阶段填充otherAuthorRatings中的author字段,同时需要按birthDate对作者文档排序,再执行$skip和$limit操作。
遇到的问题:
- 当
$sort、$skip、$limit放在填充阶段(unwind/lookup/group)之后时,查询结果排序正常; - 但将这些阶段放在填充之前时,
$sort无法正确排序,返回结果无序。
希望将$sort、$skip、$limit放在填充前的原因:
- 可以限制需要填充的文档数量,减少不必要的关联查询;
- 排序操作能利用索引提升性能(若
$sort放在unwind/lookup/group之后则无法使用索引)。
补充:排序仅针对作者文档的birthDate字段,与填充后的内嵌字段无关。
示例文档
{ _id: 1, name: "foo", birthDate: "2022-12-24T00:00:00.000+00:00", otherAuthorRatings: [ { author: 3, rating: 5 } ], }, { _id: 2, name: "bar", birthDate: "2022-12-25T00:00:00.000+00:00", otherAuthorRatings: [ { author: 1, rating: 4 }, { author: 3, rating: 5 }, ], }, { _id: 3, name: "baz", birthDate: "2022-12-26T00:00:00.000+00:00", otherAuthorRatings: [], },
解决方案
经排查,$group阶段会打乱之前的排序结果,因此需要在$group阶段之后重新执行一次$sort操作。由于此时数据已经经过前置的$skip和$limit限制,数据量较小,重新排序的性能开销可以忽略。
内容的提问来源于stack exchange,提问作者Guna Shekar
相关产品推荐
相关产品推荐

