我理解Compound Multikey Indexes May Only Include One Array Field。
以下不会产生“无法索引并行数组”错误:
db.test.ensureIndex({"values.x": 1, "values.y": 1})
db.test.insert({"values": [ {"x": 1, "y": 2}, {"x": 2, "y": 2} ]})
db.test.insert({"values": [ {"x": 2, "y": 1}, {"x": 1, "y": 1} ]})
db.test.insert({"values": [ {"x": 1, "y": 1}, {"x": 1, "y": 1} ]})
因此,似乎允许在多个对象属性中使用复合索引,其中对象嵌套在一个数组字段中。
文档说“MongoDB分别索引数组中的每个值”,因此对于上面的场景,我期望在每个文档中创建值x和值的所有组合的索引条目。
但是,对两个嵌套字段的以下查询都表明只使用复合索引中的第一个字段 - nscanned为2表示Mongo必须检查第二个添加的文档,以检查数组元素上的y = 2匹配x = 2。
db.test.find({"values.x": 2, "values.y": 2}).explain()
{
"cursor" : "BtreeCursor values.x_1_values.y_1",
"isMultiKey" : true,
"n" : 1,
"nscannedObjects" : 2,
"nscanned" : 2,
"nscannedObjectsAllPlans" : 2,
"nscannedAllPlans" : 2,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"values.x" : [
[
2,
2
]
],
"values.y" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost:27017"
}
MongoDB索引和复合索引有什么价值,只覆盖第一个字段?
答案 0 :(得分:0)
如果您使用$elemMatch查询运算符搜索同一元素中的x
和y
值,您会看到索引边界也适用于y
:
> db.test.find({ values: { $elemMatch: { x: 2, y: 2 }}}).explain()
{
"cursor" : "BtreeCursor values.x_1_values.y_1",
"isMultiKey" : true,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"values.x" : [
[
2,
2
]
],
"values.y" : [
[
2,
2
]
]
},
"server" : "localhost:27017"
}
这是针对SERVER-3104中的2.4实施的。故障单说明解释了为什么这些索引边界不能用于原始查询:
在多个字段上创建复合索引时,Mongo不会计算笛卡尔积。如果文档
{ a:[ { b:1, c:2 }, { b:10, c:20 } ] }
根据索引{ 'a.b':1, 'a.c':1 }
编制索引,则 创建的索引键是{ '':1, '':2 }
和{ '':10, '':20 }
。 (例如,没有索引键{'':1,'':20}。)现在,假设我们有一个查询
{ 'a.b':1, 'a.c':20 }
。此查询应与文档匹配,因为文档中存在“a.b”值1,文档中存在“a.c”值20。但是,没有索引键包含'a.b'位置的1和'a.c'位置的20。因此,'a.b'上的索引边界将为[[ 1, 1 ]]
,但'a.c'上不会有任何索引边界。这意味着将检索索引键{ '':1, '':2 }
并用于查找完整文档,匹配器将确定完整文档与查询匹配