我不理解这个mongodb行为,我的集合有以下索引(名称为了清晰起见而简化)并且包含~50k文档。
{
"v" : 1,
"key" : {
"a" : 1,
"b" : -1
},
"ns" : "db.articles",
"name" : "a_1_b_-1",
"background" : false,
"dropDups" : false
}
以下查询
db.articles.find({ a: {"$in": ["foo", "bar"] } }).sort({b: -1}).limit(10).explain()
返回:
{
"cursor" : "BtreeCursor a_1_b_-1 multi",
"isMultiKey" : false,
"n" : 10,
"nscannedObjects" : 20,
"nscanned" : 21,
"nscannedObjectsAllPlans" : 68,
"nscannedAllPlans" : 105,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"a" : [
[
"foo",
"foo"
],
[
"bar",
"bar"
]
],
"b" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "localhost:27017"
}
“scanAndOrder”为true表示索引中的顺序不能用于对返回集进行排序。这意味着当给定偏移量(即跳过10000)时查询将会阻塞,随后将返回“没有索引的sort()太多数据。添加索引或指定更小的限制”。 当查询被更改为仅执行单个相等性检查时,将按预期使用索引:
db.articles.find({ a: "foo" }).sort({b: -1}).limit(10).explain()
结果集顺序现在是文档在索引中的顺序:
"scanAndOrder" : false
所以它似乎与“$ in”运算符在索引查找中的行为有关吗?
答案 0 :(得分:1)
MongoDB中的复合索引存储在树状数据结构中,例如,假设我们在a
和b
字段上创建索引,对于a
的每个值,都会关联b
值列表。
BTree游标的$in
运算符返回a
值的引用列表,因此sort
运算符必须在排序之前合并多个b
值列表,并且没有索引可以之后使用。