检索复合索引的一部分

时间:2020-09-17 19:41:26

标签: mongodb database-indexes mongodb-indexes

我有一个大集合,我想检索按两个字段排序的结果。但是,我想以一种高效的方式从结果的深处开始检索结果。

例如,如果文档是:

{ age: 25, name: "Gabe" }
{ age: 25, name: "John" }
{ age: 25, name: "Mike" }
{ age: 26, name: "Gabe" }
{ age: 26, name: "John" }
{ age: 26, name: "Mike" }

我想检索按{age:1,name:1}排序的文档。我想直接索引到{age:26,name:“ John”}中,并按照复合索引的顺序检索下N个文档(例如,{age:26,name:“ Mike”})。目的是将分页的搜索结果返回给用户。

1 个答案:

答案 0 :(得分:0)

这正是mongodb索引查询的工作方式。

MongoDB索引类似于b树结构。当使用复合索引进行选择和排序时,查询执行程序将开始扫描第一个匹配值的索引,并扫描最后一个匹配项。然后将识别出的文档取回去,以进行进一步的查询。

某些查询可能需要扫描多个索引范围。在示例查询中,扫描索引的单个范围将按顺序查找所有匹配的文档,因此不需要其他排序。

此查询将需要两部分,一部分与第一个年龄和姓名的部分列表匹配,一个与其余的年龄匹配。可以使用"Error on line 1 at column 1: Document is empty Below is a rendering of the page up to the first error." 运算符来完成。

为了证明这一点,我使用了explain和executeStats选项:

$or

获胜计划显示两次索引扫描,并将其结果传递到合并阶段。请注意,提取阶段不会再进行任何过滤,并且没有内存中排序:

db.collection.explain("executionStats").find({$or:[{age:{$eq:25},name:{$gte:"John"}},{age:{$gt:25}}]}).sort({age:1,name:1})

executionStats部分显示查询执行程序检查了2个索引键和2个文档,此查询返回的文档总数为2:

"winningPlan" : {
            "stage" : "SUBPLAN",
            "inputStage" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "SORT_MERGE",
                    "sortPattern" : {
                        "age" : 1,
                        "name" : 1
                    },
                    "inputStages" : [
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "age" : 1,
                                "name" : 1
                            },
                            "indexName" : "age_1_name_1",
                            "isMultiKey" : false,
                            "multiKeyPaths" : {
                                "age" : [ ],
                                "name" : [ ]
                            },
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 2,
                            "direction" : "forward",
                            "indexBounds" : {
                                "age" : [
                                    "[25.0, 25.0]"
                                ],
                                "name" : [
                                    "[\"John\", {})"
                                ]
                            }
                        },
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "age" : 1,
                                "name" : 1
                            },
                            "indexName" : "age_1_name_1",
                            "isMultiKey" : false,
                            "multiKeyPaths" : {
                                "age" : [ ],
                                "name" : [ ]
                            },
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 2,
                            "direction" : "forward",
                            "indexBounds" : {
                                "age" : [
                                    "(25.0, inf.0]"
                                ],
                                "name" : [
                                    "[MinKey, MaxKey]"
                                ]
                            }
                        }
                    ]
                }
            }
        },

(我的笔记本电脑动力不足,因此该查询实际上花了3毫秒)

相关问题