我正在开发一个使用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" }
如您所见,结果是相同的。但是我不确定使用索引来获取排序数据是一种好习惯,但是(有时)使用聚合管道比创建索引要花更多的精力。
那么,哪个是最佳选择?
答案 0 :(得分:0)
在问题的上下文中,更好的选择是聚合,因为它明确指定了排序。
在查询示例中,因为查询使用的是索引{ num: 1, marked: 1, value: 1}
,所以将按索引指定的顺序返回结果。但是,查询中指定的任何内容都不能保证排序,这意味着结果将来可能会有所变化。例如,考虑要创建索引{ num: 1, marked: 1, updated_at: 1 }
的情况。查询计划者可能决定改用该索引,这可能导致结果以不同的顺序出现。
在没有排序的情况下,查询将按所使用索引的顺序返回结果,但如果未明确指定该顺序,则不应依赖该顺序。引用docs:
除非您指定sort()方法或使用$ near运算符, MongoDB不保证查询结果的顺序。