Limites de índice de várias chaves
Nesta página
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.
Limites de interseção para o índice de várias chaves
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 compostos para índice multichave
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 ] ]
.
Índice composto em um campo de array
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 ] ] }
Query de faixa em um campo indexado escalar (WiredTiger)
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. |
Índice composto em campos a partir de uma array de documentos incorporados
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"
.
Limites compostos de campo sem array e campo de um array
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.
Limites compostos de campos de índice a partir de uma array
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" ] ] }
query sem $elemMatch
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 ] ] }
$elemMatch
em caminho incompleto
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 } } } )