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

Limites de índice de várias chaves

Nesta página

  • Interseção de limites para um índice de múltiplas chaves
  • Exemplo: interseção de limites
  • query sem $elemMatch
  • Limites compostos para um índice multichave
  • Exemplo: Limites compostos do campo não-array e do campo array
  • Exemplo: limites compostos de campo que não é de array e múltiplos campos de array
  • Limites compostos de vários campos da mesma array
  • Exemplo: $elemMatch em caminho do campo divergentes

Os limites do índice definem o intervalo de valores de índice que o MongoDB procurar ao usar um índice para atender a uma query. Quando você especifica vários predicados de query em um campo indexado, o MongoDB tenta combinar os limites desses predicados para produzir uma varredura de índice com limites menores. Limites de índice menores resultam em query mais rápidas e uso reduzido de recursos.

O MongoDB combina limites por limites deinterseção ou composição .

A interseção de limites refere-se ao ponto onde vários limites se sobrepõem. Por exemplo, dado os limites [ [ 3, Infinity ] ] e [ [ -Infinity, 6 ] ], a interseção dos limites resulta em [ [ 3, 6 ] ].

Dado um campo de array indexado, considere uma query que especifica múltiplos predicados de query na array e usa um índice de múltiplas chaves para atender a query. O MongoDB pode cruzar os limites do índice de múltiplas chaves se um operador $elemMatch se juntar aos predicados da query.

O exemplo a seguir mostra como o MongoDB usa a interseção de limites para definir um intervalo menor de valores para a query, resultando em um desempenho de query aprimorado.

1

Crie uma collection students que contenha documento com um campo name e um campo de array grades:

db.students.insertMany(
[
{ _id: 1, name: "Shawn", grades: [ 70, 85 ] },
{ _id: 2, item: "Elena", grades: [ 92, 84 ] }
]
)
2

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

db.students.createIndex( { grades: 1 } )
3

Execute a seguinte query:

db.students.find( { grades : { $elemMatch: { $gte: 90, $lte: 99 } } } )

A query anterior usa $elemMatch para retornar documentos em que a array grades contém pelo menos um elemento que corresponde a ambas as condições especificadas.

Considerando os predicados da query separadamente:

  • Os limites para o predicado maior ou igual a 90 ($gte: 90) são [ [ 90, Infinity ] ].

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

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

ratings: [ [ 90, 99 ] ]

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 esta query:

db.students.find( { grades: { $gte: 90, $lte: 99 } } )

A query pesquisa a array grades para:

  • Pelo menos um elemento maior ou igual a 90

  • Pelo menos um elemento menor ou igual a 99

O mesmo elemento pode satisfazer ambos os critérios.

Como a query anterior não usa $elemMatch, o MongoDB não cruza os limites. Em vez disso, o MongoDB usa um dos seguintes limites:

  • [ [ 90, Infinity ] ]

  • [ [ -Infinity, 99 ] ]

O MongoDB não garante qual dos dois limites escolhe.

Os limites compostos combinam limites para múltiplas chaves de um índice composto. O uso de limites de várias chaves reduz o tempo necessário para processar uma query porque o MongoDB não precisa calcular os resultados de cada limite individualmente.

Por exemplo, considere um índice composto { temperature: 1, humidity: 1 } com os seguintes limites:

  • temperature tem um limite de [ [ 80, Infinity ] ].

  • humidity tem um limite de [ [ -Infinity, 20 ] ].

A composição dos limites resulta no uso de ambos os limites:

{ temperature: [ [ 80, Infinity ] ], humidity: [ [ -Infinity, 20 ] ] }

Se o MongoDB não puder compor os dois limites, o MongoDB restringirá a varredura do índice pelo limite no campo principal. Neste exemplo, o campo principal é temperature, resultando em uma restrição de temperature: [ [ 80, Infinity ] ].

O exemplo a seguir mostra como o MongoDB usa limites compostos para definir uma restrição de query mais eficiente, resultando em um melhor desempenho da query.

1

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 ] }
]
)
2

Crie um índice composto de múltiplas chaves nos campos item e ratings :

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

Execute a seguinte query:

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

A query anterior especifica uma condição em ambas as chaves do índice (item e ratings).

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 usa os limites combinados de:

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

O exemplo a seguir mostra como o MongoDB usa limites compostos quando um índice inclui um campo que não é de array e vários campos de array.

1

Crie uma collection survey2 que contenha documento com um campo de string item e um campo de array ratings:

db.survey2.insertMany( [
{
_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" } ]
}
] )
2

Crie um índice composto nos seguintes campos:

  • item (não array)

  • ratings.score (array)

  • ratings.by (array)

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

Execute a seguinte query:

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 compõe 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 compõe com o campo item .

O MongoDB atende à query de uma das seguintes maneiras:

  • O MongoDB compõe os limites item com os limites "ratings.score" :

    {
    "item" : [ [ "XYZ", "XYZ" ] ],
    "ratings.score" : [ [ -Infinity, 5 ] ],
    "ratings.by" : [ [ MinKey, MaxKey ] ]
    }
  • O MongoDB compõe os limites item com os limites "ratings.by" :

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

Para combinar os limites de "ratings.score" com os limites de "ratings.by", a query deve usar $elemMatch.

Para compor os limites das chaves de índice da mesma array, ambos os itens a seguir devem ser verdadeiros:

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

  • 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").

O exemplo a seguir mostra como o MongoDB combina limites para chaves de índice da mesma array. Este exemplo utiliza a coleção survey2 utilizada no exemplo anterior.

1

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.

2

Execute a seguinte query:

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

A query anterior usa $elemMatch no campo ratings para exigir que a array contenha pelo menos um único elemento que corresponda a ambas as condições.

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 compõe os dois limites para os seguintes limites:

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

Se sua query especificar $elemMatch em campos que divergem de um caminho comum, o MongoDB não poderá compor os limites de chaves de índice da mesma array.

O exemplo seguinte demonstra $elemMatch em caminho do campo divergentes.

1

Criar uma collection survey3 contém documento com um campo de string item e um campo de array ratings:

db.survey3.insertMany( [
{
_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" }
]
}
] )
2

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". Para compor os limites do índice composto, uma query deve usar $elemMatch no caminho do campo comum.

3

A seguinte consulta usa um $elemMatch que não está no caminho exigido:

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

O MongoDB não pode compor os limites do índice e o campo "ratings.scores.q2" não é limitado durante a varredura do índice.

Para combinar os limites, a query deve usar $elemMatch no caminho comum "ratings.scores":

db.survey3.find( { 'ratings.scores': { $elemMatch: { 'q1': 2, 'q2': 8 } } } )
← Criar um Índice em um Campo Incorporado em uma Array