检索复合索引的一部分

问题描述

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

例如,如果文档是:

{ 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”})。目的是将分页搜索结果返回给用户

解决方法

这正是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","indexBounds" : {
                                "age" : [
                                    "(25.0,inf.0]"
                                ],"name" : [
                                    "[MinKey,MaxKey]"
                                ]
                            }
                        }
                    ]
                }
            }
        },

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...