2012-11-27 10 views
10

Ho cercato in array (multi-key) indicizzazione sui MongoDB e ho le seguenti domande che non sono stato in grado di trovare molta documentazione su:Capire un indice su una serie di documenti secondari

indici su una serie di documenti secondari

Quindi, se ho un campo di matrice che assomiglia a:

{field : [ 
    {a : "1"}, 
    {b : "2"}, 
    {c : "3"} 
    ] 
} 

sto eseguendo la query solo su field.a e field.c individ dualmente (non entrambi insieme), credo di avere una scelta tra le seguenti alternative:

  1. db.Collection.ensureIndex({field : 1});
  2. db.Collection.ensureIndex({field.a : 1}); db.Collection.ensureIndex({field.c : 1});

Cioè: un indice sulla intera matrice; o due indici sui campi incorporati. Ora le mie domande sono:

  • Come si fa a visualizzare un indice sull'intero array in opzione 1 (è ancora utile)? A quali domande è utile un indice del genere?
  • Data la situazione di interrogazione che ho descritto, quale delle due opzioni precedenti è migliore e perché?
+2

+1 per una domanda ben formata. –

+0

@Aid cosa hai finito? Come sono stati i risultati? –

+0

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

risposta

7

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.

+0

Significa che se il mio array crescerà di dimensioni, posso comunque indicizzarlo con "fields.a"? O non dovrei indicizzare un array crescente in qualsiasi forma? – KevinResoL

Problemi correlati