我今天早上花了大部分时间重新阅读MongoDB docs,blog和其他答案,我仍然遗漏了一些我希望的东西对别人来说是非常明显的。
编辑:我已经将文档的方案更改为没有子文档(元数据。*),并且仍然存在索引未被覆盖的问题。我删除了现有的索引,并用新的索引重新编入索引:所以我没有:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.daily"
},
{
"v" : 1,
"key" : {
"host" : 1,
"cid" : 1,
"title" : 1,
"urls" : 1,
"global" : -1,
"current" : -1,
"total" : -1
},
"name" : "byHostTotals",
"ns" : "test.daily"
},
{
"v" : 1,
"key" : {
"host" : 1,
"cid" : 1,
"title" : 1,
"urls" : 1,
"total" : -1,
"global" : -1,
"current" : -1
},
"name" : "byHostCurrents",
"ns" : "test.daily"
}
]
鉴于此查询:
db.daily.find({'host': 'example.com'}, {'_id': 0, 'cid': 1, 'title': 1, 'current': 1}).hint("byHostCurrents").sort({'current': -1}).limit(10).explain()
未显示为名为" byHostCurrent"的索引所涵盖:
{
"clauses" : [
{
"cursor" : "BtreeCursor byHostCurrents",
"isMultiKey" : true,
"n" : 10,
"nscannedObjects" : 1090,
"nscanned" : 1111,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"host" : [
[
"example.com",
"example.com"
]
],
"cid" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"title" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"total" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"global" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"current" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor ",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"host" : [
[
"usatoday.com",
"usatoday.com"
]
],
"cid" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"title" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"total" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"global" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"current" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 10,
"nscannedObjects" : 1090,
"nscanned" : 1111,
"nscannedObjectsAllPlans" : 1090,
"nscannedAllPlans" : 1111,
"scanAndOrder" : false,
"nYields" : 8,
"nChunkSkips" : 0,
"millis" : 9,
"server" : "ubuntu:27017",
"filterSet" : false
}
MongoDB版本是:2.6.3。
答案 0 :(得分:3)
所以这里很瘦......
查询时:
db.daily.find({'host': 'example.com'}, {'_id': 0, 'cid': 1, 'title': 1, 'current': 1}).hint("byHostCurrents").sort({'current': -1}).limit(10);
如果我没有.sort(),那么它将使用索引,但是因为我现在使用排序,索引字段的ORDER变得很重要。
对于上面使用索引的查询,我需要创建一个这样的新索引:
db.daily.ensureIndex({'current': -1, 'host': 1, 'cid': 1, 'title': 1});
现在有了这个索引,我们将获得indexOnly:true,因为我们以相反的顺序(降序)向下查看总电流,我们只需扫描索引中所需的条目数。符合'host'='example.com'并限制要求。
总的来说,我必须有4个额外的索引来支持我的查询:
按主机排序按主机排序的内容(如下所示)
db.daily.ensureIndex({'host':1,'current': - 1,'cid':1,'title':1});
所以MongoDB文档对这些事情的解释并不十分清楚,特别是在查看排序问题时。他们缺少的是,如果要使用排序,则必须在等于查询后包含前缀字段或包括所有前缀字段。
例如根据我的问题提供原始索引:
db.daily.ensureIndex({"host" : 1, "cid" : 1, "title" : 1, "urls" : 1, "global" : -1, "current" : -1, "total" : -1});
如果我希望索引涵盖查询,那么我必须改变:
db.daily.find({'host': 'example.com'}, {'_id': 0, 'cid': 1, 'title': 1, 'current': 1}).hint("byHostCurrents").sort({'current': -1}).limit(10);
To This:
db.daily.find({'host': 'example.com'}, {'_id': 0, 'cid': 1, 'title': 1, 'current': 1}).hint("byHostCurrents").sort({'cid':1, 'title':1, 'urls': 1, 'global: 1, 'current': -1}).limit(10);
这不是我想要的。
希望这有助于将来。