Los límites de una exploración de índices definen las partes de un índice que se deben buscar durante una query. Cuando existen múltiples predicados sobre un índice, MongoDB intenta combinar los límites de estos predicados, ya sea por intersección o compuesto, para producir una exploración con límites más pequeños.
Límites de intersección para el índice multikey
La intersección de límites se refiere a una conjunción lógica (es decir, AND) de múltiples límites. Por instancia, dados dos límites [ [ 3, Infinity ] ] y [ [ -Infinity, 6 ] ], la intersección de los límites da como resultado [ [ 3, 6 ] ].
Dada una indexado campo de arreglo, considere una query que especifique múltiples predicados en el arreglo y pueda utilizar un índice multiclave. MongoDB puede cruzar los límites del índice multiclave si un $elemMatch une los predicados.
Por ejemplo, crea una colección de survey que contenga documentos con un campo item y un campo de array ratings:
db.survey.insertMany( [ { _id: 1, item: "ABC", ratings: [ 2, 9 ] }, { _id: 2, item: "XYZ", ratings: [ 4, 3 ] } ] )
Cree un índice multiclave en el arreglo ratings:
db.survey.createIndex( { ratings: 1 } )
La siguiente consulta utiliza para exigir que la $elemMatch matriz contenga al menos un único elemento que coincida con ambas condiciones:
db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )
Tomando cada uno de los predicados por separado:
los límites para el predicado mayor o igual a 3 (es decir,
$gte: 3) son[ [ 3, Infinity ] ];Los límites para el predicado menor o igual a 6 (es decir,
$lte: 6) son[ [ -Infinity, 6 ] ].
Debido a que la consulta utiliza para unir estos predicados, MongoDB puede intersecar los límites $elemMatch para:
ratings: [ [ 3, 6 ] ]
Si la query does not une las condiciones del campo de arreglo con $elemMatch, MongoDB no puede cruzar los límites del índice multiclave. Considere la siguiente query:
db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )
La consulta busca en la ratings matriz al menos un elemento mayor o igual a 3 y al menos un elemento menor o igual a 6. Dado que un solo elemento no necesita cumplir ambos criterios, MongoDB no interseca los límites y utiliza [ [ 3,
Infinity ] ] [ [ -Infinity, 6 ] ]o. MongoDB no garantiza cuál de estos dos límites elige.
Límites compuestos para índices multiclave
Los límites compuestos se refieren al uso de límites para varias claves de un índice compuesto. Por ejemplo, con un índice compuesto { a: 1, b: 1 } con límites en el campo a de [ [
3, Infinity ] ] y límites en el campo b de [ [ -Infinity, 6 ]
], combinar los límites resulta en el uso de ambos límites:
{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }
Si MongoDB no puede combinar los dos límites, MongoDB siempre restringe el escaneo del índice por el límite en su campo principal, en este caso, a:
[ [ 3, Infinity ] ].
Índice compuesto en un campo de arreglo
Considera un índice compuesto de varias claves; es decir, un índice compuesto donde uno de los campos indexados es un arreglo. Por ejemplo, crea una colección de survey que contenga documentos con un campo item y un campo de arreglo ratings:
db.survey.insertMany( [ { _id: 1, item: "ABC", ratings: [ 2, 9 ] }, { _id: 2, item: "XYZ", ratings: [ 4, 3 ] } ] )
Crea un índice compuesto en el campo item y el campo ratings:
db.survey.createIndex( { item: 1, ratings: 1 } )
La siguiente consulta especifica una condición en ambas claves del índice:
db.survey.find( { item: "XYZ", ratings: { $gte: 3 } } )
Tomando cada uno de los predicados por separado:
los límites para el predicado
item: "XYZ"son[ [ "XYZ", "XYZ" ] ];los límites para el predicado
ratings: { $gte: 3 }son[ [ 3, Infinity ] ].
MongoDB puede combinar los dos límites para utilizar los límites combinados de:
{ item: [ [ "XYZ", "XYZ" ] ], ratings: [ [ 3, Infinity ] ] }
Consultas de rango en un campo indexado escalar (WiredTiger)
Solo para los motores de almacenamiento WiredTiger y In-Memory,
En los índices multiclave, MongoDB registra qué campo o campos indexados hacen que un índice sea multiclave. El seguimiento de esta información permite al motor de consultas de MongoDB utilizar límites de índice más estrictos.
El índice compuesto mencionado anteriormente está en el campo escalar [1] item y el campo de ratings matriz:
db.survey.createIndex( { item: 1, ratings: 1 } )
Para WiredTiger y los motores de almacenamiento en memoria, si una operación de query especifica varios predicados en el(los) campo(s) escalar(es) indexado(s) de un índice compuesto multikey, MongoDB intersectará los límites para el campo.
Por ejemplo, la siguiente operación especifica una query de rango en el campo escalar, así como una query de rango en el campo de arreglo:
db.survey.find( { item: { $gte: "L", $lte: "Z"}, ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )
MongoDB intersectará los límites de item a [ [ "L", "Z" ] ] y las valoraciones de [[3.0, 6.0]] para usar los límites combinados de:
"item" : [ [ "L", "Z" ] ], "ratings" : [ [3.0, 6.0] ]
Por otro ejemplo, considera el caso donde los campos escalares pertenecen a un documento anidado. Por ejemplo, crear una colección survey que contenga los siguientes documentos:
db.survey.insertMany( [ { _id: 1, item: { name: "ABC", manufactured: 2016 }, ratings: [ 2, 9 ] }, { _id: 2, item: { name: "XYZ", manufactured: 2013 }, ratings: [ 4, 3 ] } ] )
Cree un índice multiclave compuesto en los campos escalares "item.name", "item.manufactured" y el campo de matriz ratings :
db.survey.createIndex( { "item.name": 1, "item.manufactured": 1, ratings: 1 } )
Considera la siguiente operación que especifica predicados de query en los campos escalares:
db.survey.find( { "item.name": "L" , "item.manufactured": 2012 } )
Para esta consulta, MongoDB puede utilizar los límites combinados de:
"item.name" : [ ["L", "L"] ], "item.manufactured" : [ [2012.0, 2012.0] ]
Las versiones anteriores de MongoDB no pueden combinar estos límites para los campos escalares.
| [1] | Un campo escalar es un campo cuyo valor no es ni un documento ni un arreglo; por ejemplo, un campo cuyo valor es una string o un entero es un campo escalar. Un campo escalar puede ser un campo anidado en un documento, siempre que el campo en sí no sea un arreglo o un documento. Por ejemplo, en el documento { a: { b: { c: 5, d: 5 } } }, c y d son campos escalares, mientras que a y b no lo son. |
Índice compuesto en campos de un arreglo de documentos incrustados
Si una matriz contiene documentos incrustados, para indexar los campos incluidos en dichos documentos, utilice el nombre del campo con puntos en la especificación del índice. Por ejemplo, dada la siguiente matriz de documentos incrustados:
ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]
El nombre de campo punteado para el campo score es "ratings.score".
Límites compuestos de campo no matricial y campo de un arreglo
Considera una colección survey2 que contiene documentos con un campo item y un campo de arreglo 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" } ] }
Cree un índice compuesto en el campo que no es item una matriz, así como dos campos de una matriz ratings.score ratings.byy:
db.survey2.createIndex( { "item": 1, "ratings.score": 1, "ratings.by": 1 } )
La siguiente consulta especifica una condición en los tres campos:
db.survey2.find( { item: "XYZ", "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )
Tomando cada uno de los predicados por separado:
los límites para el predicado
item: "XYZ"son[ [ "XYZ", "XYZ" ] ];los límites para el predicado
score: { $lte: 5 }son[ [ -Infinity, 5 ] ];los límites para el predicado
by: "anon"son[ "anon", "anon" ].
MongoDB puede combinar los límites de la item clave con "ratings.score" los de "ratings.by" o, según los predicados de la consulta y los valores de la clave del índice. MongoDB no garantiza qué límites combinará con el item campo. Por ejemplo, MongoDB combinará los item límites con los "ratings.score" de:
{ "item" : [ [ "XYZ", "XYZ" ] ], "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ MinKey, MaxKey ] ] }
O bien, MongoDB puede optar por combinar los límites item con los límites "ratings.by":
{ "item" : [ [ "XYZ", "XYZ" ] ], "ratings.score" : [ [ MinKey, MaxKey ] ], "ratings.by" : [ [ "anon", "anon" ] ] }
Sin embargo, para combinar los límites de "ratings.score" con los límites de "ratings.by", la consulta debe utilizar $elemMatch. Consulta Límites compuestos de campos de índice de un arreglo para más información.
Límites compuestos de campos de índice de un arreglo
Para combinar juntos los límites para las claves de índice del mismo arreglo:
las claves del índice deben compartir la misma ruta de campo hasta, pero sin incluir, los nombres de los campos, y
la query debe especificar predicados sobre los campos utilizando
$elemMatchen esa ruta.
Para un campo en un documento incrustado, el nombre "a.b.c.d"del campo con puntos, como, es la ruta del d campo. Para combinar los límites de las claves de índice de la misma matriz,$elemMatch debe estar en la ruta hasta el nombre del campo, pero sin incluirlo; es decir,. "a.b.c"
Por ejemplo, cree un índice compuesto en ratings.score los ratings.by campos y:
db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )
Los campos "ratings.score" y "ratings.by" comparten la ruta de campo ratings. La consulta siguiente utiliza $elemMatch en el campo ratings para requerir que el arreglo contenga al menos un elemento único que cumpla con ambas condiciones:
db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )
Tomando cada uno de los predicados por separado:
los límites para el predicado
score: { $lte: 5 }son[ [ -Infinity, 5 ] ];los límites para el predicado
by: "anon"son[ [ "anon", "anon" ] ].
MongoDB puede combinar los dos límites para utilizar los límites combinados de:
{ "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }
query Without $elemMatch
Si la consulta no une las condiciones de los campos de la matriz indexada $elemMatch con, MongoDB no puede combinar sus límites. Considere la siguiente consulta:
db.survey2.find( { "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )
Debido a que un único documento incrustado en el arreglo no necesita cumplir ambos criterios, MongoDB no compone los límites. Cuando se utiliza un índice compuesto, si MongoDB no puede restringir todos los campos del índice, MongoDB siempre restringe el campo principal del índice, en este caso "ratings.score":
{ "ratings.score": [ [ -Infinity, 5 ] ], "ratings.by": [ [ MinKey, MaxKey ] ] }
$elemMatch en camino incompleto
Si la consulta no especifica $elemMatch en la ruta de los campos embebidos, hasta pero excluyendo los nombres de los campos, MongoDB no puede componer los límites de las claves del índice del mismo arreglo.
Por ejemplo, una colección survey3 contiene documentos con un campo item y un campo de arreglo 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" } ] }
Crea un índice compuesto en los campos ratings.scores.q1 y ratings.scores.q2:
db.survey3.createIndex( { "ratings.scores.q1": 1, "ratings.scores.q2": 1 } )
Los campos "ratings.scores.q1" y "ratings.scores.q2" comparten la ruta de campo "ratings.scores" y el debe estar en esa $elemMatch ruta.
Sin embargo, la siguiente consulta utiliza un pero no en la ruta $elemMatch requerida:
db.survey3.find( { ratings: { $elemMatch: { 'scores.q1': 2, 'scores.q2': 8 } } } )
Por lo tanto, MongoDB no puede combinar los límites, y el campo "ratings.scores.q2" quedará sin restricciones durante el escaneo del índice. Para combinar los límites, la query debe utilizar $elemMatch en la ruta "ratings.scores":
db.survey3.find( { 'ratings.scores': { $elemMatch: { 'q1': 2, 'q2': 8 } } } )