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
$elemMatchnesse 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 } } } )