我有一个集合学生,文档很少
[{id:1, name:'AA'}, {id:2, name:'BB'}]
我正在获取按文档中不存在的字段排序的文档
db.students.find().sort({marks: -1})
它按顺序给我文档
[{id:1, name:'AA'}, {id:2, name:'BB'}]
现在我添加索引
db.students.createIndex({'marks':1})
然后调用相同的查询
db.students.find().sort({marks: -1})
订单已更改!
[{id:2, name:'BB'},{id:1, name:'AA'}]
索引字段如何影响缺少该字段的文档的排序顺序?
注意:这可能不是一个有效的示例。但是我的问题是类似的。
答案 0 :(得分:1)
Mongodb将在两个不同的时间执行排序。
无索引:
当我们在mongodb中执行排序(在排序字段上没有索引)时,将在查询时间内通过扫描整个集合开始对集合进行排序。
排序的方向将是向前的(偶数:-1),即它将首先按其插入顺序(_id值)触摸文档。
当遇到两个具有相同字段的文档(标记:两个文档为null)时,它将使用_id值对其进行排列。
具有索引:
您以升序在标记字段上创建了索引(索引不过是生成以键为标记的B树)。
当我们尝试使用mark:1对集合进行排序时,我们将以索引顺序获得相同的结果。
当我们尝试对带有标记:-1的集合进行排序时,由于已经按升序对索引进行了索引(排序)的文档,mongodb将开始从向后返回文档。
这就是为什么我们得到不同结果的原因。
对这些查询执行explain()
后,您可以获得有关这些查询的更多详细信息。
无索引:
db.students2.find().sort({marks:-1}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "stackoverflow.students2",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [ ]
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"marks" : -1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [ ]
},
"direction" : "forward"
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "sys2030",
"port" : 27017,
"version" : "3.2.22",
"gitVersion" : "105adca0d443f9a1a5abd608fd7133840a68dd"
},
"ok" : 1
}
我们没有索引,因此mongodb在查询时间开始对其进行扫描。
具有索引:
db.students.find().sort({marks:-1}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "stackoverflow.students",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [ ]
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"marks" : 1
},
"indexName" : "marks_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "backward",
"indexBounds" : {
"marks" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "sys2030",
"port" : 27017,
"version" : "3.2.22",
"gitVersion" : "105adca0d443f9a1a5abd608fd7133840a68dd"
},
"ok" : 1
}
我们有了index,因此mongodb开始使用它,并简单地从向后返回结果(标记:-1)。
这是我们在收集量很大时执行排序的原因,monogodb会给出以下错误:具有大量数据的排序,而没有索引。
进一步阅读:
https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/