Я столкнулся с проблемами при переносе простого .find().sort().skip().limit()
в Aggregation Framework, что привело к нарушению разбиения на страницы: один и тот же документ появился на нескольких страницах.Наконец, я понял, что $limit
влияет на порядок результатов $sort
.Ниже я описываю, как воспроизвести шаги, чтобы увидеть проблему (проверено в Mongo 3.4.17 и 3.6.7).
> // 1. Create a simple coleection and fill it with test data:
> for(var i = 0; i < 10; ++i) db.SomeCollection.insert({sortField: "just_some_string"});
> db.SomeCollection.count();
10
>
> // 2. Check, that with .find().sort().limit() the order of results does not depend on the `limit()`'s value:
db.SomeCollection.find().sort({"sortField": 1}).limit(5)
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb531"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb532"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb533"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb534"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb535"), "sortField" : "just_some_string" }
> db.SomeCollection.find().sort({"sortField": 1}).limit(8)
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb531"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb532"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb533"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb534"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb535"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb536"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb537"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb538"), "sortField" : "just_some_string" }
>
> // 3. Logically the same query but using Aggregation Framework
> db.SomeCollection.aggregate([{$sort: {"sortField": 1}}, {$limit: 5}]);
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb534"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb535"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb532"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb531"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb533"), "sortField" : "just_some_string" }
> db.SomeCollection.aggregate([{$sort: {"sortField": 1}}, {$limit: 8}]);
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb538"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb535"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb532"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb534"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb536"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb531"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb533"), "sortField" : "just_some_string" }
{ "_id" : ObjectId("5ba3ddf3a07260b77dddb537"), "sortField" : "just_some_string" }
Мои вопросы:
- Почему
.aggregate()
с $ sort, за которым следует $ limit, дает другой порядок результатов, чем .find().sort().limit()
? - Почему порядок результатов в
.aggregate()
зависит от значения $limit
?