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.
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? –
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
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? –