我有这个系列:
db.place.find() :
{
_id : "p1",
alterNames : ["abcd","abcD"],
population : 122
}
{
_id : "p2",
alterNames : ["qsdf","qsDF"],
population : 100
}
我想找到以“ab”开头的 alterNames 的文档,并按人口对其进行排序。
我创建了索引:{alterNames : 1, population : -1}
我的查询:
db.place.find({alterNames : /^ab/}).sort({population : -1}).limit(10).explain()
我等着看"n" = "nScannedObjects" = 10
我得到了什么:
"n" = 10
"nScannedObjects" = 4765
我错过了什么吗?
编辑: 以下是完整的解释:
db.place.find({alterNames : /^pari/ }).sort({population : -1}).limit(10).explain()
"clauses" : [
{
"cursor" : "BtreeCursor alterNames_1_population_-1",
"isMultiKey" : true,
"n" : 10,
"nscannedObjects" : 4765,
"nscanned" : 4883,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"alterNames" : [
[
"pari",
"parj"
],
[
/^pari/,
/^pari/
]
],
"population" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor ",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"alterNames" : [
[
"pari",
"parj"
],
[
/^pari/,
/^pari/
]
],
"population" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 10,
"nscannedObjects" : 4765,
"nscanned" : 4883,
"nscannedObjectsAllPlans" : 4765,
"nscannedAllPlans" : 4883,
"scanAndOrder" : false,
"nYields" : 890,
"nChunkSkips" : 0,
"millis" : 396,
"server" : "localhost:27017",
"filterSet" : false
答案 0 :(得分:1)
你的记谱很混乱。我假设你的集合包含的文档看起来像places
数组中的两个文档。
> db.test.find()
{ "_id" : "p1", "alterNames" : [ "abcd", "abcD" ], "population" : 122 }
{ "_id" : "p2", "alterNames" : [ "qsdf", "qsDF" ], "population" : 100 }
对于像/^ab/
这样的左锚定正则表达式,MongoDB将查询转换为实际上是范围查询的查询,并且可以有效地使用索引
{ "alterNames" : /^ab/ } => { "alterNames" : { "$gte" : "ab", "$lt" : "ac" } }
与范围匹配的每个值(例如"abcd"
)对于population
(多键)值为alterNames
的文档,其索引值低于"abcd"
。要以population
- 顺序返回匹配的文档,MongoDB必须对从每个匹配存储桶返回的文档进行外部排序。我相信这是你的更高nscannedObjects的来源。如果你查看解释(这可能很好地包含在内),你应该找到scanAndOrder : true
。