以下是我的环境详情: 我从here获得了示例MongoDB集合或数据库。它创造了一个餐厅系列。一份文件如下:
{
"_id" : ObjectId("5a6292fd6b741ed385c94524"),
"address" : {
"building" : "97-22",
"coord" : [
-73.8601152,
40.7311739
],
"street" : "63 Road",
"zipcode" : "11374"
},
"borough" : "Queens",
"cuisine" : "Jewish/Kosher",
"grades" : [
{
"date" : ISODate("2014-11-24T00:00:00.000Z"),
"grade" : "Z",
"score" : 20
},
{
"date" : ISODate("2013-01-17T00:00:00.000Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2012-08-02T00:00:00.000Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2011-12-15T00:00:00.000Z"),
"grade" : "B",
"score" : 25
}
],
"name" : "Tov Kosher Kitchen",
"restaurant_id" : "40356068"
}
我创建了两个索引,如:
db.restaurants.createIndex({"restaurant_id" : 1}, {"name" : "restaurantsid"})
db.restaurants.createIndex({"address.zipcode" : 1}, {"name" : "zipcode"})
索引如下:
> db.restaurants.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.restaurants"
},
{
"v" : 2,
"key" : {
"address.zipcode" : 1
},
"name" : "zipcode",
"ns" : "test.restaurants"
},
{
"v" : 2,
"key" : {
"restaurant_id" : 1
},
"name" : "restaurantsid",
"ns" : "test.restaurants"
}
]
我想在这里实现的是我在下面的查询中需要完整的restaurant_id或者zipCodes列表。我知道有一个索引存在于记忆中。我写了一个这样的查询:
db.restaurants.find({}, {"address.zipcode" : 1, "_id" : 0}).explain()
结果是:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"address.zipcode" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "COLLSCAN",
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "714fc0d524cf",
"port" : 27017,
"version" : "3.6.0",
"gitVersion" : "a57d8e71e6998a2d0afde7edc11bd23e5661c915"
},
"ok" : 1
}
它总是给我" stage" :" COLLSCAN"。
所以现在让我们得到所有的对象id。 MongoDB在ObjectId上创建了一个默认索引。
db.restaurants.find({}, {"_id" : 1}).explain()
结果是:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 1
},
"inputStage" : {
"stage" : "COLLSCAN",
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "714fc0d524cf",
"port" : 27017,
"version" : "3.6.0",
"gitVersion" : "a57d8e71e6998a2d0afde7edc11bd23e5661c915"
},
"ok" : 1
}
奇怪的是MongoDB没有达到索引,但我需要的所有数据都存在于索引中。为什么获奖计划是" COLLSCAN"总是?
与restaurantsid指数相同。也许我错过了什么。
在编写查询时我也照顾"_id" : 0
。
每次都必须使用hint()来使用这样的索引:
> db.restaurants.explain("executionStats").find({}, {"address.zipcode" : 1, "_id" : 0}).hint("zipcode")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"address.zipcode" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"address.zipcode" : 1
},
"indexName" : "zipcode",
"isMultiKey" : false,
"multiKeyPaths" : {
"address.zipcode" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"address.zipcode" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 25359,
"executionTimeMillis" : 79,
"totalKeysExamined" : 25359,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 25359,
"executionTimeMillisEstimate" : 63,
"works" : 25360,
"advanced" : 25359,
"needTime" : 0,
"needYield" : 0,
"saveState" : 199,
"restoreState" : 199,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"address.zipcode" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 25359,
"executionTimeMillisEstimate" : 43,
"works" : 25360,
"advanced" : 25359,
"needTime" : 0,
"needYield" : 0,
"saveState" : 199,
"restoreState" : 199,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"address.zipcode" : 1
},
"indexName" : "zipcode",
"isMultiKey" : false,
"multiKeyPaths" : {
"address.zipcode" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"address.zipcode" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 25359,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "714fc0d524cf",
"port" : 27017,
"version" : "3.6.0",
"gitVersion" : "a57d8e71e6998a2d0afde7edc11bd23e5661c915"
},
"ok" : 1
}
在命令行使用MongoDB提示很好,但是当有应用程序运行时它们很糟糕,并且它们无法从代码中使用hint()。为什么MongoDB不能在不使用hint()的情况下自行使用正确的索引?