MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Indici multichiave MongoDB e limiti di intersezione degli indici

MongoDB offre un ottimo supporto per gli array e offre molta flessibilità nella modalità documento. Ad esempio, puoi incorporare array nei documenti e anche incorporare documenti in array, ecc. Tuttavia, lavorare con gli array ha una serie di trucchi in MongoDB. In questo post, esamineremo alcuni dei problemi che MongoDB ha con gli indici e gli array.

Indici multichiave

In MongoDB, puoi indicizzare un campo dell'array per creare una voce di indice per ogni elemento dell'array. L'indice risultante è chiamato indice "multichiave". Gli indici multichiave possono essere creati su valori scalari o documenti incorporati. Per ulteriori informazioni sugli indici multichiave, fai riferimento a questa documentazione.

Gli indici multichiave, sebbene utili, hanno diverse limitazioni:

  • Se crei un indice multichiave composto, hai almeno un campo che è un array.
  • Un indice composto non può essere una chiave shard.
  • Un indice composto non può essere un indice hash.
Limitazioni dell'indice multikey MongoDB - A cosa prestare attenzione nelle tue queryFai clic per twittare

Uno degli aspetti più interessanti degli indici multichiave è il modo in cui vengono calcolati i limiti di intersezione dell'indice.

Indice Interseca Limiti

Ecco come la documentazione di MongoDB definisce i limiti di intersezione dell'indice:

“I limiti di una scansione dell'indice definiscono le parti di un indice in cui cercare durante una query. Quando esistono più predicati su un indice, MongoDB tenterà di combinare i limiti per questi predicati tramite intersezionecomposto per produrre una scansione con limiti più piccoli."

Query sugli intervalli sugli array

Iniziamo con un semplice esempio per vedere come MongoDB calcola i limiti di indice per le query sugli array. Supponiamo di avere i seguenti tre documenti in una raccolta:

{x: 65}
{x: 35}
{x: [12,95]}

Emettiamo la seguente domanda:

db.coll.find({x :{ $gt :22, $lt:55})

La domanda è abbastanza semplice. Ti aspetteresti che la risposta sia {x:35} ma la query restituisce:

{x:35}
{x:[25,95]}

Il motivo deriva dal modo in cui MongoDB gestisce gli array. Lo stesso elemento dell'array non deve necessariamente soddisfare entrambe le condizioni; finché c'è un elemento che soddisfa ogni condizione, è una corrispondenza. Quindi, in questo caso, i limiti sono [22, Infinito] e [-Infinito, 55]. Poiché non viene utilizzato un operatore "elemMatch", MongoDB non utilizza l'intersezione dell'indice. MongoDB non specifica quale di questi intervalli [22, Infinity] o [-Infinity, 55] verrà utilizzato per l'esecuzione della query.

Se vogliamo utilizzare l'intersezione dell'indice, dobbiamo utilizzare la seguente query:

db.coll.find(x :{ $elemMatch:{$gt :22,$lt:55}})

Quando lo usi, MongoDB interseca i limiti dell'indice e usa [22, 55] come limiti. Come previsto, questa query non restituisce alcun risultato (elemMatch non corrisponde a non array). Quindi, essenzialmente, le query di intervallo sugli array sono abbastanza inutili senza l'operatore $elemMatch.

Indici multichiave composti:combinazione di campi array e non array

Considera una collezione con i seguenti documenti:

{item: 35, prices:[250,35]}
......
{item: 106, prices:[1500,65]}

Aggiungeremo un indice composto su questa raccolta:

db.ensureIndex({item:1, prices:1});

Ora eseguiamo una semplice query:

db. coll. find({item: {$gt:12, $lt:65}});

La query sembra abbastanza semplice, poiché stiamo utilizzando un elemento non array con un intervallo fisso. Mi aspetto che i limiti di intersezione dell'indice siano qualcosa di simile a item:[[12,65] ] per la query, tuttavia, se esegui una spiegazione vedrai questo:

"indexBounds" : {
"item" : [ [ -Infinity, 65 ] ],
"prices" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ]
},

Il motivo è che MongoDB rileva che si tratta di un indice multichiave e non elabora l'intersezione dei limiti dell'indice, indipendentemente dal fatto che la query non utilizzi alcun campo dell'array. La morale della storia è che quando mescoli campi array e non array in un indice, tieni sempre d'occhio i limiti di intersezione dell'indice. È probabile che non sia efficiente.