Lei ha ragione che se si sta eseguendo la query solo sul valore di un campo nella matrice, entrambi gli indici si, in un certo senso, aiutare a fare la query più performante.
Tuttavia, uno sguardo ai seguenti 3 domande:
> db.zaid.save({field : [{a: 1}, {b: 2}, {c: 3}] });
> db.zaid.ensureIndex({field:1});
> db.zaid.ensureIndex({"field.a":1});
#Query 1
> db.zaid.find({"field.a":1})
{ "_id" : ObjectId("50b4be3403634cff61158dd0"), "field" : [ { "a" : 1 }, { "b" : 2 }, { "c" : 3 } ] }
> db.zaid.find({"field.a":1}).explain();
{
"cursor" : "BtreeCursor field.a_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"field.a" : [
[
1,
1
]
]
}
}
#Query 2
> db.zaid.find({"field.b":1}).explain();
{
"cursor" : "BasicCursor",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
#Query 3
> db.zaid.find({"field":{b:1}}).explain();
{
"cursor" : "BtreeCursor field_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"field" : [
[
{
"b" : 1
},
{
"b" : 1
}
]
]
}
}
Si noti che la seconda query non dispone di un indice su di esso, anche se l'array indicizzato, ma il terzo query non. Scegliere gli indici in base al modo in cui si intende interrogare i dati è importante quanto valutare se l'indice stesso è ciò di cui si ha bisogno. In Mongo, la struttura del tuo indice può e fa una grande differenza sul rendimento delle tue query se non stai attento. Penso che questo spieghi la tua prima domanda.
La tua seconda domanda è un po 'più aperta, ma penso che la risposta, ancora una volta, risiede nel modo in cui ti aspetti di interrogare i tuoi dati. Se ti interesserà sempre solo la corrispondenza con i valori di "fields.a", dovresti salvare spazio nella memoria per altri indici che potresti aver bisogno in fondo alla strada. Se, tuttavia, è altrettanto probabile che esegua una query su uno qualsiasi di questi elementi nell'array e si è ragionevolmente certi che l'array non crescerà all'infinito (mai indicizzare su un array che potenzialmente aumenterà nel tempo a una dimensione non associata. non sarà in grado di indicizzare i documenti quando l'array raggiunge 1024 byte in BSON.), quindi è necessario indicizzare l'array completo. Un esempio di questo potrebbe essere un documento per una mano di carte da gioco che contiene un array che descrive ciascuna carta in una mano dell'utente. Puoi indicizzare su questo array senza timore di traboccare oltre il limite delle dimensioni dell'indice poiché una mano non potrebbe mai avere più di 52 carte.
+1 per una domanda ben formata. –
@Aid cosa hai finito? Come sono stati i risultati? –
@Kevin per questa specifica opzione di query 2 ha funzionato meglio.Se stai interrogando per l'equivalenza sull'intero contenuto dell'array, l'opzione 1 è migliore. –