【发布时间】:2018-09-20 18:25:57
【问题描述】:
我在将简单的.find().sort().skip().limit() 迁移到聚合框架时遇到了问题,导致分页中断:同一个文档出现在多个页面上。最后,我意识到$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的值?
【问题讨论】:
标签: mongodb aggregation-framework