2013-02-15 126 views
1

我明白Compound Multikey Indexes May Only Include One Array FieldMongoDB如何處理嵌套在數組中的對象屬性的複合索引?

下列不產生「不能索引平行陣列」錯誤:

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將數組中的每個值分別索引」,因此對於上述場景,我預計要創建的每個文檔中的values.x和values.y的所有組合的索引條目。

但是,對兩個嵌套字段的以下查詢表明,只有複合索引中的第一個字段被使用 - 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

如果使用$elemMatch查詢操作員相同的元素中搜索xy值,你會看到指數界限也適用於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 does not compute a cartesian product when creating a compound index on multiple fields. If the document { a:[ { b:1, c:2 }, { b:10, c:20 } ] } is indexed according to index { 'a.b':1, 'a.c':1 } , the index keys created are { '':1, '':2 } and { '':10, '':20 } . (There is no index key { '':1, '':20 } for example.)

Now, suppose we have a query { 'a.b':1, 'a.c':20 } . This query is supposed to match the document, because an 'a.b' value of 1 exists in the document, and an 'a.c' value of 20 exists in the document. However, there is no index key containing both 1 in the 'a.b' position and 20 in the 'a.c' position. As a result, the index bounds on 'a.b' will be [[ 1, 1 ]] but there will not be any index bounds on 'a.c'. This means the index key { '':1, '':2 } will be retrieved and used to find the full document, and the Matcher will determine that the full document matches the query

相關問題