Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ /

Limites de índice de várias chaves

Nesta página

  • Limites de interseção para o índice de várias chaves
  • Limites compostos para índice multichave

Os limites de uma varredura de índice definem as partes de um índice a serem pesquisadas durante uma consulta. Quando existirem vários predicados sobre um índice, o MongoDB tentará combinar os limites para esses predicados, por interseção ou composição, para produzir uma varredura com limites menores.

A interseção de limites refere-se a uma conjunção lógica (ou seja AND) de múltiplos limites. Por exemplo, dados dois limites [ [ 3, Infinity ] ] e [ [ -Infinity, 6 ] ], a interseção dos limites resulta em [ [ 3, 6 ] ].

Dado um campo de arrayindexado , considere uma query que especifique múltiplos predicados na array e possa usar um índice de múltiplas chaves. O MongoDB pode cruzar os limites do índice de várias chaves se um $elemMatch se juntar aos predicados.

Por exemplo, crie uma collection survey que contenha documento com um campo item e um campo de array ratings:

db.survey.insertMany(
[
{ _id: 1, item: "ABC", ratings: [ 2, 9 ] },
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }
]
)

Criar um índice de múltiplas chaves na array ratings :

db.survey.createIndex( { ratings: 1 } )

A query a seguir usa $elemMatch para exigir que a array contenha pelo menos um único elemento que corresponda a ambas as condições:

db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )

Considerando os predicados separadamente:

  • os limites para o predicado maior ou igual a 3 (ou seja, $gte: 3) são [ [ 3, Infinity ] ];

  • os limites para o predicado menor ou igual a 6 (ou seja, $lte: 6) são [ [ -Infinity, 6 ] ].

Como a query usa $elemMatch para unir esses predicados, o MongoDB pode cruzar os limites para:

ratings: [ [ 3, 6 ] ]

Se a query não unir as condições no campo de array com $elemMatch, o MongoDB não poderá cruzar os limites do índice de múltiplas chaves. Considere a seguinte query:

db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )

A query pesquisa a array ratings em busca de pelo menos um elemento maior ou igual a 3 e pelo menos um elemento menor ou igual a 6. Como um único elemento não precisa atender a ambos os critérios, o MongoDB não cruza os limites e usa [ [ 3, Infinity ] ] ou [ [ -Infinity, 6 ] ]. O MongoDB não garante qual desses dois limites ele escolhe.

Limites de composição refere-se ao uso de limites para múltiplas chaves do índice composto. Por exemplo, dado um índice composto { a: 1, b: 1 } com limites no campo a de [ [ 3, Infinity ] ] e limites no campo b de [ [ -Infinity, 6 ] ], compor os limites resulta no uso de ambos os limites:

{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }

Se o MongoDB não puder compor os dois limites, o MongoDB sempre restringirá a varredura do índice pelo limite em seu campo principal, neste caso, a: [ [ 3, Infinity ] ].

Considere um índice composto de várias chaves; ou seja, um índice composto onde um dos campos indexados é um array. Por exemplo, crie uma collection survey que contenha documento com um campo item e um campo de array ratings:

db.survey.insertMany(
[
{ _id: 1, item: "ABC", ratings: [ 2, 9 ] },
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }
]
)

Crie um índice composto no campo item e no campo ratings :

db.survey.createIndex( { item: 1, ratings: 1 } )

A seguinte query especifica uma condição em ambas as chaves do índice:

db.survey.find( { item: "XYZ", ratings: { $gte: 3 } } )

Considerando os predicados separadamente:

  • os limites para o predicado item: "XYZ" são [ [ "XYZ", "XYZ" ] ];

  • os limites para o predicado ratings: { $gte: 3 } são [ [ 3, Infinity ] ].

O MongoDB pode compor os dois limites para usar os limites combinados de:

{ item: [ [ "XYZ", "XYZ" ] ], ratings: [ [ 3, Infinity ] ] }

Apenas para os mecanismos de armazenamento WiredTiger e In-memory,

No índice de múltiplas chaves, o MongoDB controla quais campos indexados fazem com que um índice seja um índice de múltiplas chaves. O rastreamento dessas informações permite que o mecanismo de query do MongoDB use limites de índice mais rígidos.

O índice composto mencionado acima está no campo escalar [1] item e no campo de array ratings:

db.survey.createIndex( { item: 1, ratings: 1 } )

Para o WiredTiger e os mecanismos de armazenamento In-memory, se uma operação de query especificar vários predicados no(s) campo(s) escalar(es) indexado(s) de um índice composto de várias chaves, o MongoDB cruzará os limites do campo.

Por exemplo, a operação a seguir especifica uma query de faixa no campo escalar, bem como uma query de faixa no campo de array:

db.survey.find( {
item: { $gte: "L", $lte: "Z"}, ratings : { $elemMatch: { $gte: 3, $lte: 6 } }
} )

O MongoDB cruzará os limites de item a [ [ "L", "Z" ] ] e as classificações para [[3.0, 6.0]] para usar os limites combinados de:

"item" : [ [ "L", "Z" ] ], "ratings" : [ [3.0, 6.0] ]

Para outro exemplo, considere onde os campos escalares pertencem a um documento aninhado. Por exemplo, crie uma coleção survey que contenha os seguintes documentos:

db.survey.insertMany(
[
{ _id: 1, item: { name: "ABC", manufactured: 2016 }, ratings: [ 2, 9 ] },
{ _id: 2, item: { name: "XYZ", manufactured: 2013 }, ratings: [ 4, 3 ] }
]
)

Crie um índice composto de múltiplas chaves nos campos escalares "item.name", "item.manufactured" e no campo de array ratings :

db.survey.createIndex( { "item.name": 1, "item.manufactured": 1, ratings: 1 } )

Considere a seguinte operação que especifica predicados de query nos campos escalares:

db.survey.find( {
"item.name": "L" ,
"item.manufactured": 2012
} )

Para esta query, o MongoDB pode usar os limites combinados de:

"item.name" : [ ["L", "L"] ], "item.manufactured" : [ [2012.0, 2012.0] ]

Versões anteriores do MongoDB não podem combinar estes limites para os campos escalares.

[1] Um campo escalar é um campo cujo valor não é um documento nem uma array; por exemplo, um campo cujo valor é uma string ou um número inteiro é um campo escalar.Um campo escalar pode ser um campo aninhado em um documento, desde que o campo em si não seja uma array ou um documento. Por exemplo, no documento { a: { b: { c: 5, d: 5 } } }, c e d são campos escalares, enquanto a e b não são.

Se uma array contiver documentos incorporados, para indexar os campos contidos nos documentos incorporados, use o nome do campo pontilhado na especificação do índice. Por exemplo, considerando a seguinte matriz de documentos incorporados:

ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]

O nome do campo pontilhado para o campo score é "ratings.score".

Considere que uma collection survey2 contém documentos com um campo item e um campo de array ratings:

{
_id: 1,
item: "ABC",
ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]
}
{
_id: 2,
item: "XYZ",
ratings: [ { score: 5, by: "anon" }, { score: 7, by: "wv" } ]
}

Crie um índice composto no campo item que não é da array, bem como em dois campos de uma array ratings.score e ratings.by:

db.survey2.createIndex( { "item": 1, "ratings.score": 1, "ratings.by": 1 } )

A seguinte query especifica uma condição em todos os três campos:

db.survey2.find( { item: "XYZ", "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )

Considerando os predicados separadamente:

  • os limites para o predicado item: "XYZ" são [ [ "XYZ", "XYZ" ] ];

  • os limites para o predicado score: { $lte: 5 } são [ [ -Infinity, 5 ] ];

  • os limites para o predicado by: "anon" são [ "anon", "anon" ].

O MongoDB pode compor os limites da chave item com os limites de "ratings.score" ou os limites de "ratings.by", dependendo dos predicados da query e dos valores da chave do índice. O MongoDB não garante quais limites ele composta com o campo item . Por exemplo, o MongoDB escolherá combinar os limites item com os limites "ratings.score" :

{
"item" : [ [ "XYZ", "XYZ" ] ],
"ratings.score" : [ [ -Infinity, 5 ] ],
"ratings.by" : [ [ MinKey, MaxKey ] ]
}

Ou o MongoDB pode optar por combinar os limites item com limites "ratings.by" :

{
"item" : [ [ "XYZ", "XYZ" ] ],
"ratings.score" : [ [ MinKey, MaxKey ] ],
"ratings.by" : [ [ "anon", "anon" ] ]
}

No entanto, para combinar os limites de "ratings.score" com os limites de "ratings.by", a query deve usar $elemMatch. Consulte Limites compostos de campos de índice a partir de uma array para obter mais informações.

Para combinar os limites das chaves de índice da mesma array:

  • as chaves de índice devem compartilhar o mesmo caminho do campo, mas excluindo os nomes dos campos, e

  • a query deve especificar predicados nos campos utilizando $elemMatch nesse caminho.

Para um campo em um documento incorporado, o nome do campo com pontos, como "a.b.c.d", é o caminho do campo para d. Para compor os limites das chaves de índice da mesma array, o $elemMatch deve estar no caminho até, mas excluindo o próprio nome do campo; ou seja, "a.b.c".

Por exemplo, crie um índice composto nos campos ratings.score e ratings.by :

db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )

Os campos "ratings.score" e "ratings.by" compartilham o caminho do campo ratings. The following query uses $elemMatch on the field ratings to require that the array contains at least one single element that matches both conditions:

db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )

Considerando os predicados separadamente:

  • os limites para o predicado score: { $lte: 5 } são [ [ -Infinity, 5 ] ];

  • os limites para o predicado by: "anon" são [ [ "anon", "anon" ] ].

O MongoDB pode compor os dois limites para usar os limites combinados de:

{ "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }

Se a query não unir as condições nos campos da array indexada com $elemMatch, o MongoDB não poderá composto seus limites. Considere a seguinte query:

db.survey2.find( { "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )

Como um único documento incorporado na array não precisa atender a ambos os critérios, o MongoDB não composta os limites. Ao usar um índice composto, se o MongoDB não puder restringir todos os campos do índice, o MongoDB sempre restringirá o campo principal do índice, neste caso "ratings.score":

{
"ratings.score": [ [ -Infinity, 5 ] ],
"ratings.by": [ [ MinKey, MaxKey ] ]
}

Se a query não especificar $elemMatch no caminho dos campos incorporados, até a exclusão dos nomes dos campos, o MongoDB não poderá compor os limites das chaves de índice da mesma array.

Por exemplo, uma collection survey3 contém documentos com um campo item e um campo de array ratings:

{
_id: 1,
item: "ABC",
ratings: [ { scores: [ { q1: 2, q2: 4 }, { q1: 3, q2: 8 } ], loc: "A" },
{ scores: [ { q1: 2, q2: 5 } ], loc: "B" } ]
}
{
_id: 2,
item: "XYZ",
ratings: [ { scores: [ { q1: 7 }, { q1: 2, q2: 8 } ], loc: "B" } ]
}

Crie um índice composto nos campos ratings.scores.q1 e ratings.scores.q2 :

db.survey3.createIndex( { "ratings.scores.q1": 1, "ratings.scores.q2": 1 } )

Os campos "ratings.scores.q1" e "ratings.scores.q2" compartilham o caminho do campo "ratings.scores" e o $elemMatch deve estar neste caminho.

A seguinte query, no entanto, utiliza um $elemMatch mas não está no caminho exigido:

db.survey3.find( { ratings: { $elemMatch: { 'scores.q1': 2, 'scores.q2': 8 } } } )

Dessa forma, o MongoDB não pode compor os limites, e o campo "ratings.scores.q2" não será limitado durante a varredura do índice. Para combinar os limites, a query deve usar $elemMatch no caminho "ratings.scores":

db.survey3.find( { 'ratings.scores': { $elemMatch: { 'q1': 2, 'q2': 8 } } } )

Voltar

Multichave