在MongoDB中没有索引字段的情况下,对字段编制索引如何影响文档的排序顺序?

时间:2019-01-03 12:04:36

标签: mongodb indexing

我有一个集合学生,文档很少

[{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'}]

索引字段如何影响缺少该字段的文档的排序顺序?

注意:这可能不是一个有效的示例。但是我的问题是类似的。

1 个答案:

答案 0 :(得分:1)

Mongodb将在两个不同的时间执行排序。

  1. 查询时间(该字段没有索引)
  2. 索引时间。 (当我们创建索引时) 因此,您对同一查询获得不同的结果。

无索引:

当我们在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/

https://docs.mlab.com/indexing/