Overview
En esta guía, puedes aprender a utilizar índices con PyMongo. Los índices pueden aumentar la eficiencia de las queries y añadir funcionalidades adicionales a la query y almacenar documentos.
Sin índices, MongoDB debe escanear todos los documentos de una colección para encontrar los que coinciden con cada consulta. Estos escaneos de colecciones son lentos y pueden afectar negativamente el rendimiento de la aplicación. Sin embargo, si existe un índice adecuado para una consulta, MongoDB puede usarlo para limitar los documentos que debe inspeccionar.
Consideraciones operativas
Para mejorar el rendimiento de las queries, cree índices en campos que aparezcan frecuentemente en las queries de su aplicación y en operaciones que devuelvan resultados ordenados. Cada índice que agregues consume espacio en disco y memoria cuando está activo, así que recomendamos que rastrees el uso de memoria y disco por parte del índice para la planificación de la capacidad. Además, cuando una operación de escritura actualiza un campo indexado, MongoDB actualiza el índice relacionado.
Como MongoDB admite esquemas dinámicos, las aplicaciones pueden consultar campos cuyos nombres no se conocen de antemano o son arbitrarios. Los índices comodín facilitan estas consultas. No están diseñados para reemplazar la planificación de índices basada en la carga de trabajo.
Para obtener más información sobre cómo diseñar tu modelo de datos y elegir los índices adecuados para tu aplicación, consulta la guía Modelado de datos e índices en el manual de MongoDB Server.
Datos de muestra
Los ejemplos de esta guía utilizan el sample_mflix.movies Colección de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte
Comience a utilizar PyMongo.
Tipos de índice
Índices de campo único y compuestos
Índices de un solo campo
Índices de campo único son índices con una referencia a un solo campo dentro de los documentos de una colección. Mejoran el rendimiento de las queries de campo único y de la ordenación, y admiten Índices TTL que remueven automáticamente documentos de una colección tras un período de tiempo determinado o en un horario definido.
Nota
El índice _id_ es un ejemplo de un índice de un solo campo. Este índice se crea automáticamente en el campo _id cuando se crea una nueva colección.
El siguiente ejemplo crea un índice en orden ascendente en el campo title. Seleccione el Synchronous o la pestaña Asynchronous para ver el código correspondiente:
movies.create_index("title")
await movies.create_index("title")
El siguiente es un ejemplo de una query que está cubierta por el índice creado en el ejemplo de código anterior:
query = { "title": "Batman" } sort = [("title", 1)] cursor = movies.find(query).sort(sort)
Para obtener más información, consulta Índices de campo único en el manual del MongoDB Server.
Índices compuestos
Índices compuestos contienen referencias a múltiples campos dentro de los documentos de una colección, mejorando el rendimiento de las consultas y la clasificación.
El siguiente ejemplo crea un índice compuesto en los campos type y genre. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
movies.create_index([("type", pymongo.ASCENDING), ("genre", pymongo.ASCENDING)])
await movies.create_index([("type", pymongo.ASCENDING), ("genre", pymongo.ASCENDING)])
El siguiente es un ejemplo de una consulta que utiliza el índice creado en el ejemplo de código anterior:
query = { "type": "movie", "genre": "Drama" } sort = [("type", pymongo.ASCENDING), ("genre", pymongo.ASCENDING)] cursor = movies.find(query).sort(sort)
Para obtener más información, se puede consultar Índices compuestos en el manual de MongoDB Server.
Índices multiclave (índices en campos de arreglos)
Los índices multiclave son índices que mejoran el rendimiento de las consultas que especifican un campo con un índice que contiene un valor de arreglo. Puede definir un índice multiclave utilizando la misma sintaxis que un índice de campo único o compuesto. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
El siguiente ejemplo crea un índice modular en el campo cast. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
result = movies.create_index("cast")
result = await movies.create_index("cast")
El siguiente es un ejemplo de una consulta que utiliza el índice creado en el ejemplo de código anterior:
query = { "cast": "Viola Davis" } cursor = movies.find(query)
Los índices multiclave se comportan de forma diferente a otros índices en cuanto a la cobertura de consultas, el cálculo de los límites de índice y el comportamiento de ordenación. Para obtener más información sobre los índices multiclave, incluyendo una explicación de su comportamiento y limitaciones, consulte la guía de índices multiclave en el manual de MongoDB Server.
MongoDB Search e índices de búsqueda vectorial
Puedes administrar tus índices de búsqueda de MongoDB y de búsqueda vectorial de MongoDB con PyMongo. Los índices especifican el comportamiento de la búsqueda y los campos que se indexarán.
MongoDB Search le permite realizar búsquedas de texto completo en colecciones alojadas en MongoDB Atlas. Los índices de MongoDB Search especifican el comportamiento de la búsqueda y qué campos indexar.
MongoDB Vector Search te permite realizar búsquedas semánticas en incrustaciones vectoriales almacenadas en MongoDB Atlas. Los índices de Vector Search definen los índices para las incrustaciones vectoriales que deseas query y los valores booleanos, de fecha, objectId, numéricos, string o UUID que deseas usar para prefiltrar tus datos.
Puedes llamar a los siguientes métodos en una colección para gestionar tus índices de búsqueda y búsqueda vectorial de MongoDB:
create_search_index()create_search_indexes()list_search_indexes()update_search_index()drop_search_index()
Nota
los métodos de gestión del índice de búsqueda de MongoDB Search se ejecutan de manera asíncrona. Los métodos del controlador pueden devolver antes de confirmar que se ejecutaron correctamente. Para determinar el estado actual de los índices, llama al método list_search_indexes().
Las siguientes secciones proporcionan ejemplos de código que demuestran cómo utilizar cada uno de los métodos anteriores.
Crear un índice de búsqueda
Se puede utilizar los métodos create_search_index() y create_search_indexes() para crear índices de MongoDB Search o índices de MongoDB Vector Search.
El siguiente ejemplo de código muestra cómo crear un único índice de búsqueda de MongoDB. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
index = { "definition": { "mappings": { "dynamic": True } }, "name": "<index name>", } collection.create_search_index(index)
index = { "definition": { "mappings": { "dynamic": True } }, "name": "<index name>", } await collection.create_search_index(index)
El siguiente ejemplo de código muestra cómo crear un único índice de MongoDB Vector Search utilizando el objeto SearchIndexModel. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
from pymongo.operations import SearchIndexModel search_index_model = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="<index name>", type="vectorSearch", ) collection.create_search_index(model=search_index_model)
from pymongo.operations import SearchIndexModel search_index_model = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="<index name>", type="vectorSearch", ) await collection.create_search_index(model=search_index_model)
Puede usar el método create_search_indexes() para crear múltiples índices. Estos índices pueden ser índices de MongoDB Search o de Vector Search. El método create_search_indexes() acepta una lista de objetos SearchIndexModel que corresponden a cada índice que deseas crear.
El siguiente ejemplo de código muestra cómo crear un índice de búsqueda de MongoDB Search y un índice de búsqueda vectorial de Atlas. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
search_idx = SearchIndexModel( definition ={ "mappings": { "dynamic": True } }, name="my_index", ) vector_idx = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="my_vector_index", type="vectorSearch", ) indexes = [search_idx, vector_idx] collection.create_search_indexes(models=indexes)
search_idx = SearchIndexModel( definition ={ "mappings": { "dynamic": True } }, name="my_index", ) vector_idx = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="my_vector_index", type="vectorSearch", ) indexes = [search_idx, vector_idx] await collection.create_search_indexes(models=indexes)
Índices de búsqueda de listas
Puedes usar el método list_search_indexes() para obtener información sobre los índices de búsqueda de MongoDB Search y Vector Search de una colección.
El siguiente ejemplo de código muestra cómo imprimir una lista de los índices de búsqueda de una colección. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
results = list(collection.list_search_indexes()) for index in results: print(index)
results = await (await collection.list_search_indexes()).to_list() async for index in results: print(index)
Actualizar un índice de búsqueda
Puede utilizar el método update_search_index() para actualizar un índice de MongoDB Search o búsqueda vectorial.
El siguiente ejemplo de código muestra cómo actualizar un índice de MongoDB Search. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
new_index_definition = { "mappings": { "dynamic": False } } collection.update_search_index("my_index", new_index)
El siguiente ejemplo de código muestra cómo actualizar un índice de MongoDB Vector Search. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
new_index_definition = { "fields": [ { "type": "vector", "numDimensions": 1536, "path": "<field to index>", "similarity": "euclidean" }, ] } collection.update_search_index("my_vector_index", new_index_definition)
new_index_definition = { "fields": [ { "type": "vector", "numDimensions": 1536, "path": "<field to index>", "similarity": "euclidean" }, ] } await collection.update_search_index("my_vector_index", new_index_definition)
Eliminar un índice de búsqueda
Puedes usar el método drop_search_index() para remover un índice de MongoDB Search o MongoDB Vector Search.
El siguiente código muestra cómo borrar un índice de búsqueda de una colección. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
collection.drop_search_index("my_index")
await collection.drop_search_index("my_index")
Text Indexes
Los índices de texto admiten consultas de búsqueda de texto en contenido de string. Estos índices pueden incluir cualquier campo cuyo valor sea un string o un arreglo de elementos de string. MongoDB admite búsqueda de texto para varios lenguajes. Puedes especificar el lenguaje por defecto como una opción al crear el índice.
Tip
MongoDB ofrece una solución mejorada de búsqueda de texto completo, MongoDB Search. Para conocer más sobre los índices de búsqueda y vectores de MongoDB y cómo utilizarlos, consulta la sección MongoDB Search and Vector Search Indexes de esta página.
Índice de texto en un solo campo
El siguiente ejemplo crea un índice de texto en el campo plot. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
movies.create_index( [( "plot", "text" )] )
await movies.create_index( [( "plot", "text" )] )
El siguiente es un ejemplo de una consulta que utiliza el índice creado en el ejemplo de código anterior:
query = { "$text": { "$search": "a time-traveling DeLorean" } } cursor = movies.find(query)
Índice de texto en varios campos
Una colección solo puede contener un índice de texto. Si quieres crear un índice de texto para múltiples campos de texto, crea un índice compuesto. Una búsqueda de texto se ejecuta en todos los campos de texto dentro del índice compuesto.
El siguiente ejemplo crea un índice de texto compuesto para los campos title y genre. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
from pymongo.collation import Collation result = myColl.create_index( [("title", "text"), ("genre", "text")], default_language="english", weights={ "title": 10, "genre": 3 }, collation=Collation(locale='fr_CA') )
from pymongo.collation import Collation result = await myColl.create_index( [("title", "text"), ("genre", "text")], default_language="english", weights={ "title": 10, "genre": 3 }, collation=Collation(locale='fr_CA') )
Para obtener más información, consulta Restricciones de índice compuesto de texto y Índices de texto en el manual de MongoDB Server.
Índices geoespaciales
MongoDB admite consultas de datos de coordenadas geoespaciales utilizando 2índices dsphere. Con un 2dsphere índice, puedes query los datos geoespaciales para inclusión, intersección y proximidad. Para obtener más información sobre cómo consultar datos geoespaciales, consulta Consultas geoespaciales.
Para crear un 2dsphere índice, debe especificar un campo que contenga únicamente objetos GeoJSON. Para más información sobre este tipo, consulte la guía de objetos GeoJSON en el manual de MongoDB Server.
El campo location.geo en el siguiente documento de ejemplo de la colección theaters en la base de datos sample_mflix es un objeto punto GeoJSON que describe las coordenadas del teatro:
{ "_id" : ObjectId("59a47286cfa9a3a73e51e75c"), "theaterId" : 104, "location" : { "address" : { "street1" : "5000 W 147th St", "city" : "Hawthorne", "state" : "CA", "zipcode" : "90250" }, "geo" : { "type" : "Point", "coordinates" : [ -118.36559, 33.897167 ] } } }
Crear un índice geoespacial
El siguiente ejemplo crea un índice 2dsphere en el campo location.geo. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
theaters.create_index( [( "location.geo", "2dsphere" )] )
await theaters.create_index( [( "location.geo", "2dsphere" )] )
MongoDB también admite 2d índices para calcular distancias en un plano euclidiano y para trabajar con la sintaxis de "pares de coordenadas heredados" utilizada en MongoDB 2.2 y versiones anteriores. Para más información, consulte la guía de consultas geoespaciales en el manual de MongoDB Server.
Unique Indexes
Los índices únicos garantizan que los campos indexados no almacenen valores duplicados. Por defecto, MongoDB crea un índice único en el campo _id durante la creación de una colección. Para crear un índice único, sigue los siguientes pasos:
Especifique el campo o la combinación de campos en los que desea evitar la duplicación.
Configura la opción
uniqueen``Verdadero``.
Crear un índice único
El siguiente ejemplo crea un índice único descendente en el campo theaterId. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
theaters.create_index("theaterId", unique=True)
await theaters.create_index("theaterId", unique=True)
Para más información, consulta la guía Índices únicos en el manual del MongoDB Server.
Índices comodín
Los índices comodín permiten realizar consultas sobre campos desconocidos o arbitrarios. Estos índices pueden ser beneficiosos si se utiliza un esquema dinámico.
Crear un índice comodín
El siguiente ejemplo crea un índice comodín ascendente en todos los valores del campo location, incluidos los valores anidados en subdocumentos y arreglos. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
movies.create_index({ "location.$**": pymongo.ASCENDING })
await movies.create_index({ "location.$**": pymongo.ASCENDING })
Para obtener más información, consulta la página Índices comodín en el manual de MongoDB Server.
Índices clusterizados
Los índices agrupados indican a una colección que almacene documentos ordenados por un valor de clave. Para crear un índice agrupado, siga estos pasos al crear su colección:
Especifique la opción de índice por clúster con el campo
_idcomo clave.Establezca el campo único en
True.
Crear un índice agrupado
El siguiente ejemplo crea un índice agrupado en el campo _id de una nueva colección movie_reviews. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
sample_mflix.create_collection("movies", clusteredIndex={ "key": { "_id": 1 }, "unique": True })
await sample_mflix.create_collection("movies", clusteredIndex={ "key": { "_id": 1 }, "unique": True })
Para obtener más información, consulte las secciones Índice agrupado y colecciones con índice clusterizado en el Manual de MongoDB Server.
Remover un índice
Puedes remover cualquier índice no utilizado, excepto el índice único por defecto en el campo _id.
Las siguientes secciones muestran cómo remover un único índice o cómo remover todos los índices de una colección.
Eliminar un solo índice
Pasa una instancia de un índice o el nombre del índice al método drop_index() para remover un índice de una colección.
El siguiente ejemplo elimina un índice llamado "_title_" de la colección movies. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
movies.drop_index("_title_")
await movies.drop_index("_title_")
Nota
No puedes remover un solo campo de un índice de texto compuesto. Debes descartar el índice completo y crear uno nuevo para actualizar los campos indexados.
Remover todos los índices
Desde MongoDB 4.2, puedes descartar todos los índices llamando al método drop_indexes() en tu colección. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
collection.drop_indexes()
await collection.drop_indexes()
Para versiones anteriores de MongoDB, pase "*" como parámetro en su llamada a drop_index() en su colección:
collection.drop_index("*")
await collection.drop_index("*")
Solución de problemas
DuplicateKeyException
Si realiza una operación de escritura que almacena un valor duplicado que viola un índice único, el controlador genera un DuplicateKeyException y MongoDB arroja un error similar al siguiente:
E11000 duplicate key error index
Información Adicional
Para obtener más información sobre los índices en MongoDB, consulta la guía de índices en el manual de MongoDB Server.
Documentación de la API
Para aprender más sobre cualquiera de los métodos o tipos analizados en esta guía, consulta la siguiente documentación de API: