2012-04-18 20 views
9

Gli indici aiutano pagina alla http://www.mongodb.org/display/DOCS/Indexes non menziona $ elemMatch e dal momento che giorni giorni per aggiungere un indice sulla mia collezione oggetto 2M + ho pensato di chiedere questo:

Sto facendo un interrogazione come:

{ lc: "eng", group: "xyz", indices: { $elemMatch: { text: "as", pos: { $gt: 1 } } } } 

Se posso aggiungere un indice

{lc:1, group:1, indices.text:1, indices.pos:1} 

sarà questa query con il componente $ elemMatch essere in grado di essere eseguito completamente attraverso l'indice?

risposta

15

Sulla base della sua domanda, immagino che i documenti sono qualcosa del tipo:

{ 
    "_id" : 1, 
    "lc" : "eng", 
    "group" : "xyz", 
    "indices" : [ 
     { 
      "text" : "as", 
      "pos" : 2 
     }, 
     { 
      "text" : "text", 
      "pos" : 4 
     } 
    ] 
} 

ho creato una collezione di prova con i documenti di questo formato, creato l'indice, e corse la query che hai postato con il .explain() opzione.

L'indice viene utilizzato come previsto:

> db.test.ensureIndex({"lc":1, "group":1, "indices.text":1, "indices.pos":1}) 
> db.test.find({ lc: "eng", group: "xyz", indices: { $elemMatch: { text: "as", pos: { $gt: 1 } } } }).explain() 
{ 
    "cursor" : "BtreeCursor lc_1_group_1_indices.text_1_indices.pos_1", 
    "isMultiKey" : true, 
    "n" : NumberLong(1), 
    "nscannedObjects" : NumberLong(1), 
    "nscanned" : NumberLong(1), 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : NumberLong(0), 
    "millis" : 0, 
    "indexBounds" : { 
     "lc" : [ 
      [ 
       "eng", 
       "eng" 
      ] 
     ], 
     "group" : [ 
      [ 
       "xyz", 
       "xyz" 
      ] 
     ], 
     "indices.text" : [ 
      [ 
       "as", 
       "as" 
      ] 
     ], 
     "indices.pos" : [ 
      [ 
       { 
        "$minElement" : 1 
       }, 
       { 
        "$maxElement" : 1 
       } 
      ] 
     ] 
    }, 
    "server" : "Marcs-MacBook-Pro.local:27017" 
} 

La documentazione sulla funzione .explain() possono essere trovate qui: http://www.mongodb.org/display/DOCS/Explain

.explain() può essere utilizzato per visualizzare informazioni su un query, compreso quale indice (se presente) viene utilizzato.

+0

Grazie Marc - e sì i miei documenti sembrano così. Noto tuttavia dal fatto che 'indexOnly' è falso. Questo non significa che il BSON doveva essere decompresso e scansionato anche se i campi sono tutti nell'indice? –

+0

Felice di aiutare! IndexOnly non è possibile con un indice multikey. Questo perché i singoli documenti incorporati hanno ciascuno la propria voce nell'indice. L'intero array "indices" non è memorizzato in una singola voce di indice. Pertanto, anche se si utilizza l'indice, è necessario leggere i documenti effettivi. Questo è spiegato nella sezione "Exact Array Matching con un indice" della documentazione "Multikeys": http://www.mongodb.org/display/DOCS/Multikeys – Marc

+0

Posso capire che se avessi chiesto 'db.test.find ({lc: "eng", group: "xyz", "indices.text:" as "," indices.pos ": {$ gt: 1}}})' senza $ elemMatch avrebbe bisogno di scansionare oggetti, ma poiché elemMatch richiede lo stesso sub-oggetto che sarebbe già nella voce di indice, no? –

Problemi correlati