MongoDB索引在执行$ elemMatch时不起作用

时间:2016-04-08 08:19:41

标签: mongodb

我正在使用$ elemMatch执行查询,似乎它没有使用我为此添加的索引。

这是我的文件:

{
  "_id" : "123466",
  "something" : [ 
        {
        "someID" : ObjectId("5701b4c3c6b126083332e66f"),
        "tags": 
        [
            {
            "tagKey": "ErrorCode",
            "tagValue": "7001"
            }, 
            {
            "tagKey": "ErrorDescription",
            "tagValue": "nullPointer"
            }
        ],
        "removeOnDelivery" : true,
        "entryTime" : ISODate("2016-04-04T00:26:43.167Z")
    }
  ]
}

以下是我正在使用的索引(我打算只使用第一个索引,但我添加了其他索引来调查它们没有工作的原因)。

db.test.createIndex( { "something.tags:" : 1 }, { sparse : true, background : true } )
db.test.createIndex( { "something.tags.tagKey:" : 1 }, { sparse : true, background : true } )
db.test.createIndex( { "something.tags.tagValue:" : 1 }, { sparse : true, background : true } )
db.test.createIndex( { "something.tags.tagKey:" : 1, "something.tags.tagValue:" : 1 }, { sparse : true, background : true } )

以下是我的查询和回复:

db.test.find({"something.tags": { $elemMatch: { "tagKey" : "ErrorCode", "tagValue" : "7001" } } } ).explain()

{
    "cursor": "BasicCursor",
    "isMultiKey": false,
    "n": 2,
    "nscannedObjects": 2,
    "nscanned": 2,
    "nscannedObjectsAllPlans": 2,
    "nscannedAllPlans": 2,
    "scanAndOrder": false,
    "indexOnly": false,
    "nYields": 0,
    "nChunkSkips": 0,
    "millis": 0,
    "server": "some_server",
    "filterSet": false,
    "stats": {
        "type": "COLLSCAN",
        "works": 4,
        "yields": 0,
        "unyields": 0,
        "invalidates": 0,
        "advanced": 2,
        "needTime": 1,
        "needFetch": 0,
        "isEOF": 1,
        "docsTested": 2,
        "children": []
    }
}

1 个答案:

答案 0 :(得分:3)

我不知道这是不是打字错误。您的createIndex查询在索引名称末尾有:。只需纠正可能会得到您想要的结果。

但是,获胜计划不一定总是选择使用索引的计划。如果COLLSCAN更便宜,如果收集的元素数量较少,Mongo可能会选择COLLSCAN。

如果要强制使用索引,可以使用.hint(“index_name”)。

我尝试使用名称中没有:的正确索引名称,并使用索引进行查询。您的结果可能会有所不同,具体取决于评论中提到的@Neil Lunn的收集统计信息和服务器版本。

db.test.createIndex( { "something.tags.tagKey" : 1 }, { sparse : true, background : true } )

解释结果,

db.test.find({"something.tags": { $elemMatch: { "tagKey" : "ErrorCode"} } } ).explain()


{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test_db.test",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "something.tags" : {
                "$elemMatch" : {
                    "tagKey" : {
                        "$eq" : "ErrorCode"
                    }
                }
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "something.tags" : {
                    "$elemMatch" : {
                        "tagKey" : {
                            "$eq" : "ErrorCode"
                        }
                    }
                }
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "something.tags.tagKey" : 1
                },
                "indexName" : "something.tags.tagKey_1",
                "isMultiKey" : true,
                "isUnique" : false,
                "isSparse" : true,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "something.tags.tagKey" : [
                        "[\"ErrorCode\", \"ErrorCode\"]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },

    "ok" : 1
}