Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

La directriz ESR (Igualdad, Ordenación, Rango)

A Índice compuesto hace referencia a varios campos y puede mejorar drásticamente los tiempos de respuesta de las query.

En la mayoría de los casos, aplicar la directriz ESR (Igualdad, Orden, Rango) para organizar las claves de índice crea un índice compuestomás eficiente.

Asegúrese de que los campos de igualdad siempre estén primero. Colocar los campos de igualdad primero mantiene el resto de los campos del índice en orden de clasificación. Elige si deseas utilizar un campo de ordenación o rango siguiente basado en las necesidades específicas de tu índice:

  • Si evitar las ordenaciones en memoria es crítico, coloca los campos de ordenación antes de los campos de rango (ESR)

  • Si el predicado de rango en la query es muy selectivo, se debe colocar antes de los campos de ordenación (ERS)

Para obtener más información sobre cómo optimizar consultas, consulta explain y Planes de consulta.

Tip

Para obligar a MongoDB a usar un índice en particular, utiliza cursor.hint() (método mongosh) al probar los índices.

Los ejemplos de esta página utilizan datos del conjunto de datos de muestra_mflix. Para obtener detalles sobre cómo cargar este conjunto de datos en su implementación autogestionada de MongoDB, consulte Cargue el conjunto de datos de muestra. Si realizaste modificaciones en las bases de datos de ejemplo, es posible que necesites descartar y volver a crear las bases de datos para ejecutar los ejemplos de esta página.

"Exacta" se refiere a una coincidencia exacta de un único valor. Las siguientes consultas de coincidencia exacta escanean la colección movies en busca de documentos cuyo campo title coincide exactamente con Equilibrium.

db.movies.find(
{ title: "Equilibrium" },
{ title: 1, year: 1, cast: 1 }
)
[
{
_id: ObjectId('573a13a3f29313caabd0c8d2'),
year: 2002,
title: 'Equilibrium',
cast: [
'Christian Bale',
'Dominic Purcell',
'Sean Bean',
'Christian Kahrmann'
]
}
]
db.movies.find(
{ title: { $eq: "Equilibrium" } },
{ title: 1, year: 1, cast: 1 }
)
[
{
_id: ObjectId('573a13a3f29313caabd0c8d2'),
year: 2002,
title: 'Equilibrium',
cast: [
'Christian Bale',
'Dominic Purcell',
'Sean Bean',
'Christian Kahrmann'
]
}
]

Las búsquedas de índices hacen un uso eficiente de las coincidencias exactas para reducir el número de claves de índice examinadas. Los campos de igualdad deben ir primero.

Un índice puede tener varias claves de igualdad. Pueden aparecer en cualquier orden entre sí, pero todas las claves de igualdad deben preceder a cualquier campo de orden o rango.

Cuanto más selectivas sean las coincidencias exactas, más eficiente será la consulta indexada.

"Ordenación" determina el orden de los resultados. Para evitar ordenaciones en memoria, coloca los campos de ordenación antes del rango en el índice.

Un índice admite operaciones de ordenación en un subconjunto de sus claves solo cuando la query incluye condiciones de igualdad en todas las claves de prefijo que preceden a las claves de ordenación. Para obtener más información, consulte Conjunto de subconjuntos de clasificación y no prefijos de un índice.

El siguiente ejemplo query la colección movies en busca de películas en las que el campo directors contenga "David Lynch". La salida está ordenada por year:

db.movies.find(
{ directors: "David Lynch" },
{ title: 1, year: 1 }
).sort( { year: 1 } )
[
{
_id: ObjectId('573a1397f29313caabce77d4'),
title: 'The Elephant Man',
year: 1980
},
{
_id: ObjectId('573a1398f29313caabce9091'),
title: 'Dune',
year: 1984
},
{
_id: ObjectId('573a1398f29313caabce9e12'),
title: 'Blue Velvet',
year: 1986
},
{
_id: ObjectId('573a1399f29313caabced630'),
year: 1992,
title: 'Twin Peaks: Fire Walk with Me'
},
{
_id: ObjectId('573a139af29313caabcf00f0'),
year: 1997,
title: 'Lost Highway'
},
{
_id: ObjectId('573a139ef29313caabcfbc0e'),
year: 1999,
title: 'The Straight Story'
},
{
_id: ObjectId('573a139ef29313caabcfbc36'),
title: 'Mulholland Drive',
year: 2001
},
{
_id: ObjectId('573a13b4f29313caabd40a54'),
title: 'Inland Empire',
year: 2006
}
]

Para mejorar el rendimiento de query, crea un índice en los campos directors y year:

db.movies.createIndex( { directors: 1, year: 1 } )
  • directors es la primera clave porque es una coincidencia exacta.

  • year se indexa en el mismo orden ( 1 ) que la query.

Campos de escaneo de filtros de "rango". El escaneo no requiere una coincidencia exacta, lo que significa que los filtros de rango están vinculados de manera flexible a las claves de índice. Para mejorar la eficiencia de las consultas, limita los límites del rango y utiliza coincidencias exactas para reducir el número de documentos a escanear.

Los filtros de rango son similares a lo siguiente:

db.movies.find(
{ runtime: { $gte: 1000 } },
{ title: 1, runtime: 1, year: 1, plot: 1 }
)
[
{
_id: ObjectId('573a1397f29313caabce69db'),
plot: 'The economic and cultural growth of Colorado spanning two centuries from the mid-1700s to the late-1970s.',
runtime: 1256,
title: 'Centennial',
year: 1978
},
{
_id: ObjectId('573a1399f29313caabcee1aa'),
plot: 'A documentary on the history of the sport with major topics including Afro-American players, player/team owner relations and the resilience of the game.',
runtime: 1140,
title: 'Baseball',
year: 1994
}
]
db.movies.find(
{ year: { $lt: 1900 } },
{ title: 1, year: 1, plot: 1 }
)
[
{
_id: ObjectId('573a139cf29313caabcf560f'),
plot: 'Two people kiss.',
title: 'The Kiss',
year: 1896
},
{
_id: ObjectId('573a13a0f29313caabd041db'),
plot: 'Two people kiss.',
title: 'The Kiss',
year: 1896
}
]
db.movies.find(
{ type: { $ne: "movie" } },
{ title: 1, year: 1, type: 1 }
)
[
{
_id: ObjectId('573a1395f29313caabce2f03'),
title: 'The Forsyte Saga',
year: 1967,
type: 'series'
},
{
_id: ObjectId('573a1396f29313caabce520d'),
title: 'Scenes from a Marriage',
year: 1973,
type: 'series'
},
{
_id: ObjectId('573a1396f29313caabce5b86'),
title: 'Ironiya sudby, ili S legkim parom!',
year: 1975,
type: 'series'
},
{
_id: ObjectId('573a1397f29313caabce6378'),
title: 'Sybil',
year: 1976,
type: 'series'
},
{
_id: ObjectId('573a1397f29313caabce6443'),
title: 'Jesus of Nazareth',
year: 1977,
type: 'series'
}
]

Si el predicado de rango en la query es muy selectivo, se debe colocar antes de los campos de ordenación para reducir el número de documentos ordenados y permitir un ordenamiento en memoria.

Para evitar una ordenación en memoria, coloque el filtro de rango después del predicado de ordenación. Para obtener más información sobre las clasificaciones en memoria, consulte cursor.allowDiskUse().

  • Los operadores de desigualdad tales como $ne o $nin son operadores de rango, no operadores exactos.

  • $regex es un operador de rango.

  • $in:

    • Cuando $in se usa solo, es un operador de igualdad que realiza una serie de coincidencias exactas.

    • Cuando $in se usa con .sort():

      • Si $in tiene menos de 201 elementos en el arreglo, los elementos se expanden y luego se combinan en el orden de clasificación especificado para el índice utilizando una etapa SORT_MERGE. Esto mejora el rendimiento de los arreglos pequeños. En este caso, $in es similar a un predicado de igualdad con ESR.

      • Si $in tiene 201 elementos o más, los elementos se ordenan como un operador de rango. En este caso, no se realiza la mejora del rendimiento para arreglos pequeños. No es posible que los campos subsiguientes en el índice se utilicen para ordenar, y $in es similar a un predicado de rango con ESR.

      • Si normalmente utiliza operadores $in con arreglos pequeños, inclúyalos antes en la especificación del índice. Si normalmente utiliza arreglos grandes, incluya los operadores $in donde incluiría un predicado de rango.

Nota

No se garantiza que el cambio de comportamiento $in en los elementos del arreglo 201 se mantenga igual en todas las versiones de MongoDB.

La siguiente query busca en la colección movies películas donde el campo directors sea "David Lynch" y el campo runtime tenga menos de 130 minutos. Los resultados están ordenados por year:

db.movies.find(
{
directors: "David Lynch",
runtime: { $lt: 130 }
},
{ title: 1, year: 1, runtime: 1 }
).sort( { year: 1 } )
[
{
_id: ObjectId('573a1397f29313caabce77d4'),
runtime: 124,
title: 'The Elephant Man',
year: 1980
},
{
_id: ObjectId('573a1398f29313caabce9e12'),
runtime: 120,
title: 'Blue Velvet',
year: 1986
},
{
_id: ObjectId('573a139ef29313caabcfbc0e'),
year: 1999,
title: 'The Straight Story',
runtime: 112
}
]

El query contiene todos los elementos de la Guía ESR:

  • directors: "David Lynch" es una coincidencia basada en igualdad

  • runtime: { $lt: 130 } es un emparejamiento basado en un rango

  • year se utiliza para la clasificación

Siguiendo la guía ESR, el índice óptimo para el query de ejemplo es:

{ directors: 1, year: 1, runtime: 1 }

Volver

Strategies

En esta página