索引与聚合管道进行排序

时间:2019-09-06 01:09:41

标签: mongodb sorting aggregation-framework mongodb-indexes

我正在开发一个使用MongoDB作为其数据库的应用程序,并且在对数据进行排序时,我遇到了一个来自同事的有趣争论,即可以使用索引而不是聚合管道来获取排序的数据。

我试过了,它确实有效;使用具有指定字段和方向的索引在查询时会返回排序后的数据。使用聚合管道时,我也获得了相同的结果。

我创建了一个具有以下规范的索引:

index name: batch_deleted_a_desc

num: asc
marked: asc
value: desc

使用聚合管道:

> db.test.aggregate([{$match: {num:"3",marked:false}}, {$sort:{"value":-1}}])
{ "_id" : ObjectId("5d70b40ba7bebd3d7c135615"), "value" : 4, "marked" : false, "num" : "3" }
{ "_id" : ObjectId("5d70b414a7bebd3d7c135616"), "value" : 2, "marked" : false, "num" : "3" }
{ "_id" : ObjectId("5d70b3fea7bebd3d7c135614"), "value" : 1, "marked" : false, "num" : "3" }

使用索引:

> db.test.find({num:"3",marked:false})
{ "_id" : ObjectId("5d70b40ba7bebd3d7c135615"), "value" : 4, "marked" : false, "num" : "3" }
{ "_id" : ObjectId("5d70b414a7bebd3d7c135616"), "value" : 2, "marked" : false, "num" : "3" }
{ "_id" : ObjectId("5d70b3fea7bebd3d7c135614"), "value" : 1, "marked" : false, "num" : "3" }

如您所见,结果是相同的。但是我不确定使用索引来获取排序数据是一种好习惯,但是(有时)使用聚合管道比创建索引要花更多的精力。

那么,哪个是最佳选择?

1 个答案:

答案 0 :(得分:0)

在问题的上下文中,更好的选择是聚合,因为它明确指定了排序

在查询示例中,因为查询使用的是索引{ num: 1, marked: 1, value: 1},所以将按索引指定的顺序返回结果。但是,查询中指定的任何内容都不能保证排序,这意味着结果将来可能会有所变化。例如,考虑要创建索引{ num: 1, marked: 1, updated_at: 1 }的情况。查询计划者可能决定改用该索引,这可能导致结果以不同的顺序出现。

在没有排序的情况下,查询将按所使用索引的顺序返回结果,但如果未明确指定该顺序,则不应依赖该顺序。引用docs

  

除非您指定sort()方法或使用$ near运算符,   MongoDB不保证查询结果的顺序。