数组上的Mongo索引

时间:2018-09-23 17:33:33

标签: mongodb

我有一个如下的Mongo文档。在这里,项目就像第一个项目在数组索引0上,第二个项目在数组索引1上,第三个项目在数组索引2上.....

{
  "_id": "234463456453643563456",
  "name": "Mike",
  "empId": "10",
  "managerId": "8",
  "projects" : [ "123", "456", "789"]
}

我在项目字段中有索引,我想搜索第一个项目为123,第二个项目为456 ...的员工...

我的索引如下,

createIndex({"projects":1});

当我进行如下搜索时,需要花费时间。

  

{“ $ or”:[{“ projects.2”:“ 123”},{“ projects.4”:“ 456”},{   “ projects.3”:“ 789”},{“ projects.1”:“ 5467”},{“ projects.0”:   “ 9768”}]}

但是,相同的查询在创建索引后效果非常好。

createIndex({"projects.0":1});
createIndex({"projects.1":1});
createIndex({"projects.2":1});
createIndex({"projects.3":1});
createIndex({"projects.4":1});
createIndex({"projects.5":1});

创建索引后,每个查询可节省3秒钟。

内部如何运作?为什么会有如此大的差异?

1 个答案:

答案 0 :(得分:1)

如果使用explain命令,很容易看到它是如何工作的。快速摘要:

我的测试集:

{
    "_id" : ObjectId("5b7fa665844b5ebfad064b1c"),
    "arr" : [ "123", "456", "789"]
},
{
    "_id" : ObjectId("5b80f96e9fceda195ba853af"),
    "arr" : [ "ABC", "DEF", "FOO"]
}

我的索引:createIndex({"arr":1})

现在,如果我以find({arr: '123'}).explain()的身份进行搜索,我们将从explain result中看到:

...
"indexName" : "_arr_",
"isMultiKey" : true,
"multiKeyPaths" : {
    "arr" : [ 
        "arr"
    ]
},
...

使用了正确的索引。现在find({arr.0: '123'}).explain()呢?

...
"winningPlan" : {
    "stage" : "COLLSCAN",
    "filter" : {
        "arr.0" : {
            "$eq" : "123"
        }
    },
    "direction" : "forward"
},
...

现在,我们获得了一个不错的完整COLLSCAN作为“获奖”计划:)。

接下来createIndex({"arr.0":1});,然后find({arr.0: '123'}).explain()给我们:

...
"winningPlan" : {
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXSCAN",
        "keyPattern" : {
            "arr.0" : 1
        },
        "indexName" : "_arr.0_",
        "isMultiKey" : false,
        "multiKeyPaths" : {
            "arr.0" : []
        },
        "isUnique" : false,
        "isSparse" : false,
        "isPartial" : false,
        "indexVersion" : 2,
        "direction" : "forward",
        "indexBounds" : {
            "arr.0" : [ 
                "[\"123\", \"123\"]"
            ]
        }
    }
}
...

因此,如您所见,如果要按数组索引搜索,arr上的multiKey索引是不够的,因为:

  

MongoDB为数组中的每个元素创建一个索引键。这些   多键索引支持对数组字段的高效查询

因此,这正是您执行初始索引时发生的事情……mongo找到包含123的文档,但是在您的情况下,您想进入需要单个索引的特定数组索引查询索引,如explain所示。

希望这对您有所帮助。