Docs Menu
Docs Home
/ /

Indexes

En esta guía, puede aprender a crear y administrar índices mediante el controlador MongoDB Kotlin.

Los índices facilitan la ejecución eficiente de consultas en MongoDB. Sin índices, MongoDB debe escanear todos los documentos de una colección (un escaneo de colección) para encontrar los documentos que coinciden con cada consulta. Estos escaneos de colección son lentos y pueden afectar negativamente el rendimiento de la aplicación. Si existe un índice adecuado para una consulta, MongoDB puede usarlo para limitar los documentos que la consulta debe inspeccionar.

Los índices también ofrecen los siguientes beneficios:

  • Los índices permiten una clasificación eficiente.

  • Los índices permiten capacidades especiales como: consultas geoespaciales.

  • Losíndices permiten la creación de restricciones para garantizar que un valor de campo sea único.

Para obtener más información, consulte Índices en el manual del servidor.

Tip

Las operaciones de actualización utilizan índices al buscar documentos para actualizar, y las operaciones de eliminación utilizan índices al buscar documentos para eliminar. Ciertas etapas del proceso de agregación también utilizan índices para mejorar el rendimiento.

Cuando ejecuta una consulta en MongoDB, su comando puede incluir varios elementos:

  • Criterios de consulta que especifican los campos y valores que estás buscando

  • Opciones que afectan la ejecución de la consulta, como la preocupación de lectura

  • Criterios de proyección para especificar los campos que devuelve MongoDB (opcional)

  • Criterios de ordenación para especificar el orden de los documentos devueltos desde MongoDB (opcional)

Cuando todos los campos especificados en la consulta, proyección y ordenación están en el mismo índice, MongoDB devuelve resultados directamente desde el índice, también llamado consulta cubierta.

Importante

Orden de clasificación

Los criterios de ordenación deben coincidir o invertir el orden del índice.

Considere un índice en el campo name en orden ascendente (AZ) y age en orden descendente (9-0):

name_1_age_-1

MongoDB utiliza este índice cuando ordena sus datos de cualquiera de las siguientes maneras:

  • name ascendente, age descendente

  • name descendente, age ascendente

Especificando un orden de clasificación de name y age ascendente o name y age descendente requiere una ordenación en memoria.

Para obtener más información sobre cómo garantizar que su índice cubra sus criterios de consulta y proyección, consulte los artículos del manual del servidor sobre cobertura de consultas.

Las siguientes pautas describen cómo puede optimizar la forma en que su aplicación utiliza los índices:

  • Para mejorar el rendimiento de las consultas, cree índices en los campos que aparecen con frecuencia en las consultas y operaciones de su aplicación que devuelven resultados ordenados.

  • Realice un seguimiento del índice de uso de la memoria y del disco para planificar la capacidad, porque cada índice que agrega consume espacio en disco y memoria cuando está activo.

  • Evite agregar índices que use con poca frecuencia. Tenga en cuenta que, cuando una operación de escritura actualiza un campo indexado, MongoDB actualiza el índice relacionado.

Dado que MongoDB admite esquemas dinámicos, las aplicaciones pueden realizar consultas en campos cuyos nombres no se pueden conocer de antemano o son arbitrarios. MongoDB 4.2 introdujo índices comodín para facilitar estas consultas. Los índices comodín 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 su modelo de datos y elegir índices apropiados para su aplicación, consulte la documentación del servidor MongoDB en Estrategias de indexación y Modelado de datos e índices.

MongoDB admite varios tipos de índices diferentes para admitir la consulta de sus datos. Las siguientes secciones describen los tipos de índice más comunes y proporcionan código de muestra para crear cada tipo de índice. Para ver una lista completa de los tipos de índices, consulta Índices en el manual del servidor.

Los siguientes ejemplos utilizan el método createIndex() para crear varios índices y las siguientes clases de datos para modelar datos en MongoDB:

// Data class for the movies collection
data class Movie(
val title: String,
val year: Int,
val cast: List<String>,
val genres: List<String>,
val type: String,
val rated: String,
val plot: String,
val fullplot: String,
)
// Data class for the theaters collection
data class Theater(
val theaterId: Int,
val location: Location
) {
data class Location(
val address: Address,
val geo: Point
) {
data class Address(
val street1: String,
val city: String,
val state: String,
val zipcode: String
)
}
}

Los índices de campo único son índices que hacen referencia a un solo campo dentro de los documentos de una colección. Mejoran el rendimiento de las consultas y la ordenación de campos únicos, y son compatibles con los índices TTL, que eliminan automáticamente los documentos de una colección después de un tiempo determinado o en una hora específica.

Nota

El índice _id_ es un ejemplo de índice de campo único. Este índice se crea automáticamente en el campo _id al crear una nueva colección.

El siguiente ejemplo crea un índice en orden ascendente en el campo title:

val resultCreateIndex = moviesCollection.createIndex(Indexes.ascending(Movie::title.name))
println("Index created: $resultCreateIndex")
Index created: title_1

El siguiente es un ejemplo de una consulta que está cubierta por el índice creado en el fragmento de código anterior:

val filter = Filters.eq(Movie::title.name, "The Dark Knight")
val sort = Sorts.ascending(Movie::title.name)
val projection = Projections.fields(
Projections.include(Movie::title.name),
Projections.excludeId()
)
data class Results(val title: String)
val resultsFlow = moviesCollection.find<Results>(filter).sort(sort).projection(projection)
resultsFlow.collect { println(it) }

Consulta la sección del manual de servidor de MongoDB sobre índices de campo único para obtener más información.

Los índices compuestos contienen referencias a múltiples campos dentro de los documentos de una colección, lo que mejora el rendimiento de las consultas y la clasificación.

Tip

Lee más sobre índices compuestos, prefijos de índice y orden de clasificación aquí.

El siguiente ejemplo crea un índice compuesto en los campos type y rated:

val resultCreateIndex = moviesCollection.createIndex(Indexes.ascending(Movie::type.name, Movie::rated.name))
println("Index created: $resultCreateIndex")
Index created: type_1_rated_1

El siguiente es un ejemplo de una consulta que está cubierta por el índice creado en el fragmento de código anterior:

val filter = Filters.and(
Filters.eq(Movie::type.name, "movie"),
Filters.eq(Movie::rated.name, "G")
)
val sort = Sorts.ascending(Movie::type.name, Movie::rated.name)
val projection = Projections.fields(
Projections.include(Movie::type.name, Movie::rated.name),
Projections.excludeId()
)
val resultsFlow = moviesCollection.find(filter).sort(sort).projection(projection)
resultsFlow.collect { println(it) }

Consulte la sección del manual del servidor MongoDB sobre índices compuestos para obtener más información.

Los índices multiclave mejoran el rendimiento de las consultas que especifican un campo con un índice que contiene un valor de matriz. Se puede definir un índice multiclave con la misma sintaxis que un índice de campo único o compuesto.

El siguiente ejemplo crea un índice compuesto de múltiples claves en los campos rated, genres (una matriz de cadenas) y title:

val resultCreateIndex =
moviesCollection.createIndex(Indexes.ascending(Movie::rated.name, Movie::genres.name, Movie::title.name))
println("Index created: $resultCreateIndex")
Index created: rated_1_genres_1_title_1

El siguiente es un ejemplo de una consulta que está cubierta por el índice creado en el fragmento de código anterior:

val filter = Filters.and(
Filters.eq(Movie::genres.name, "Animation"),
Filters.eq(Movie::rated.name, "G")
)
val sort = Sorts.ascending(Movie::title.name)
val projection = Projections.fields(
Projections.include(Movie::title.name, Movie::rated.name),
Projections.excludeId()
)
val resultsFlow = moviesCollection.find(filter).sort(sort).projection(projection)
resultsFlow.collect { println(it) }

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 Índices multiclave en el manual del servidor.

Puede administrar mediante programación sus índices MongoDB Search y MongoDB Vector Search utilizando el controlador Kotlin.

La función de búsqueda de MongoDB permite realizar búsquedas de texto completo en colecciones alojadas en MongoDB. Para obtener más información sobre la búsqueda de MongoDB, consulte la documentación de los índices de búsqueda de MongoDB.

La Búsqueda Vectorial de MongoDB permite realizar búsquedas semánticas en incrustaciones vectoriales almacenadas en MongoDB. Para obtener más información sobre la Búsqueda Vectorial de MongoDB, consulte Guíade búsqueda vectorial de MongoDB.

Puede llamar a los siguientes métodos en una colección para administrar sus índices MongoDB Search y MongoDB Vector Search:

  • createSearchIndex() (válido solo para índices de búsqueda de MongoDB)

  • createSearchIndexes()

  • listSearchIndexes()

  • updateSearchIndex()

  • dropSearchIndex()

Nota

Los métodos de gestión de índices de MongoDB Search se ejecutan de forma asíncrona. Los métodos del controlador pueden regresar antes de confirmar su correcta ejecución. Para determinar el estado actual de los índices, llame al método listSearchIndexes().

Las siguientes secciones proporcionan ejemplos de código que demuestran cómo utilizar cada uno de los métodos anteriores.

Puede usar el método createSearchIndex() para crear un único índice de búsqueda de MongoDB. No puede usar este método para crear un índice de búsqueda vectorial de MongoDB.

Puedes utilizar el createSearchIndexes() para crear varios índices de MongoDB Search o MongoDB Vector Search. Debe crear una instancia de SearchIndexModel para cada índice y luego pasar una lista de instancias SearchIndexModel al método createSearchIndexes().

El siguiente ejemplo de código muestra cómo crear un índice de búsqueda de MongoDB:

val searchIdx = Document(
"mappings",
Document("dynamic", true)
)
val resultCreateIndex = moviesCollection.createSearchIndex("myIndex", searchIdx)

Para crear varios índices de búsqueda o búsqueda vectorial, debe crear una instancia de SearchIndexModel para cada índice.

El siguiente ejemplo de código muestra cómo crear índices de búsqueda y búsqueda vectorial en una sola llamada:

val searchIdxMdl = SearchIndexModel(
"searchIdx",
Document("analyzer", "lucene.standard").append(
"mappings", Document("dynamic", true)
),
SearchIndexType.search()
)
val vectorSearchIdxMdl = SearchIndexModel(
"vsIdx",
Document(
"fields",
listOf(
Document("type", "vector")
.append("path", "embeddings")
.append("numDimensions", 1536)
.append("similarity", "dotProduct")
)
),
SearchIndexType.vectorSearch()
)
val resultCreateIndexes = moviesCollection.createSearchIndexes(
listOf(searchIdxMdl, vectorSearchIdxMdl)
)

Puede utilizar el método listSearchIndexes() para devolver una lista de los índices de búsqueda de MongoDB en una colección.

El siguiente ejemplo de código muestra cómo imprimir una lista de los índices de búsqueda en una colección:

val searchIndexesList = moviesCollection.listSearchIndexes().toList()

Puede utilizar el método updateSearchIndex() para actualizar un índice de búsqueda de MongoDB.

El siguiente código muestra cómo actualizar un índice de búsqueda:

moviesCollection.updateSearchIndex(
"myIndex",
Document("analyzer", "lucene.simple").append(
"mappings",
Document("dynamic", false)
.append(
"fields",
Document(
"title",
Document("type", "string")
)
)
)
)

Puede utilizar el método dropSearchIndex() para eliminar un índice de búsqueda de MongoDB.

El siguiente código muestra cómo eliminar un índice de búsqueda de una colección:

moviesCollection.dropSearchIndex("myIndex");

Los índices de texto admiten consultas de texto sobre contenido de cadena. Estos índices pueden incluir cualquier campo cuyo valor sea una cadena o un array de elementos de cadena. MongoDB admite consultas de texto en varios idiomas. Puede especificar el idioma predeterminado al crear el índice.

Tip

MongoDB ofrece una solución mejorada de búsqueda de texto completo: MongoDB Search. Para obtener más información sobre los índices de MongoDB Search y cómo usarlos, consulte la sección "MongoDB Search" y "MongoDB Vector Search Indexes" de esta guía.

El siguiente ejemplo crea un índice de texto en el campo plot:

try {
val resultCreateIndex = moviesCollection.createIndex(Indexes.text(Movie::plot.name))
println("Index created: $resultCreateIndex")
} catch (e: MongoCommandException) {
if (e.errorCodeName == "IndexOptionsConflict") {
println("there's an existing text index with different options")
}
}
Index created: plot_text

El siguiente es un ejemplo de una query cubierto por el índice creado en el snippet de código anterior. Ten en cuenta que se omite el sort porque los índices de texto no contienen orden de clasificación.

val filter = Filters.text("Batman")
val projection = Projections.fields(
Projections.include(Movie::fullplot.name),
Projections.excludeId()
)
data class Results(val fullplot: String)
val resultsFlow = moviesCollection.find<Results>(filter).projection(projection)
resultsFlow.collect { println(it) }

Una colección solo puede contener un índice de texto. Si desea crear un índice de texto para varios campos de texto, debe crear un índice compuesto. Una consulta de texto se ejecuta en todos los campos de texto dentro del índice compuesto.

El siguiente fragmento crea un índice de texto compuesto para los campos title y genre:

try {
val resultCreateIndex = moviesCollection.createIndex(
Indexes.compoundIndex(
Indexes.text(Movie::title.name), Indexes.text(Movie::genres.name)
)
)
println("Index created: $resultCreateIndex")
} catch (e: MongoCommandException) {
if (e.errorCodeName == "IndexOptionsConflict") {
println("there's an existing text index with different options")
}
}
Index created: title_text_genre_text

Para obtener más información, consulte las siguientes entradas del Manual del servidor:

MongoDB admite consultas de datos de coordenadas geoespaciales mediante 2índices dsphere. Con un 2dsphere índice, puede consultar los datos geoespaciales por inclusión, intersección y proximidad. Para obtener más información sobre la consulta de datos geoespaciales, consulte Consultas geoespaciales en el manual del servidor.

Para crear un 2dsphere índice, debe especificar un campo que contenga únicamente objetos GeoJSON. Para obtener más información sobre este tipo, consulte Objetos GeoJSON en el manual del servidor.

El campo location.geo en el siguiente documento de muestra 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
]
}
}
}

El siguiente ejemplo crea un índice 2dsphere en el campo location.geo:

val resultCreateIndex = theatersCollection.createIndex(
Indexes.geo2dsphere("${Theater::location.name}.${Theater.Location::geo.name}")
)
println("Index created: $resultCreateIndex")
Index created: location.geo_2dsphere

Importante

Intentar crear un índice geoespacial en un campo que ya está cubierto por un índice geoespacial genera un error.

El siguiente es un ejemplo de una consulta geoespacial que está cubierta por el índice creado en el fragmento de código anterior:

// MongoDB Headquarters in New York, NY.
val refPoint = Point(Position(-73.98456, 40.7612))
val filter = Filters.near(
"${Theater::location.name}.${Theater.Location::geo.name}",
refPoint, 1000.0, 0.0
)
val resultsFlow = theatersCollection.find(filter)
resultsFlow.collect { println(it) }

MongoDB también admite 2d índices para calcular distancias en un plano euclidiano. Para obtener más información, consulte Consultas geoespaciales en el manual del servidor.

Los índices únicos garantizan que los campos indexados no almacenen valores duplicados. De forma predeterminada, MongoDB crea un índice único en el campo _id durante la creación de una colección. Para crear un índice único, especifique el campo o la combinación de campos que desea evitar la duplicación y configure la opción unique como true.

El siguiente ejemplo crea un índice descendente único en el campo theaterId:

try {
val indexOptions = IndexOptions().unique(true)
val resultCreateIndex = theatersCollection.createIndex(
Indexes.descending(Theater::theaterId.name), indexOptions
)
println("Index created: $resultCreateIndex")
} catch (e: DuplicateKeyException) {
println("duplicate field values encountered, couldn't create index: \t${e.message}")
}
Index created: theaterId_-1

Importante

Si realiza una operación de escritura que almacena un valor duplicado que viola el índice único, el controlador genera un DuplicateKeyException y MongoDB arroja un error similar al siguiente:

E11000 duplicate key error index

Consulte la página Índices únicos en el manual del servidor MongoDB para obtener más información.

Los índices agrupados indican a una colección que almacene documentos ordenados por un valor de clave. Para crear un índice agrupado, especifique la opción de índice agrupado con el _id campo como clave y el campo único al true crear la colección.

El siguiente ejemplo crea un índice agrupado en el campo _id de la colección vendors:

val clusteredIndexOptions = ClusteredIndexOptions(Document("_id", 1), true)
val createCollectionOptions = CreateCollectionOptions().clusteredIndexOptions(clusteredIndexOptions)
database.createCollection("vendors", createCollectionOptions)

Consulte las secciones del manual del servidor MongoDB para obtener más información:

Puede eliminar cualquier índice no utilizado excepto el índice único predeterminado en el campo _id.

Las siguientes secciones muestran las formas de remover índices:

  • Uso de un documento de especificación de índice

  • Uso de un campo de nombre indexado

  • Usando un carácter comodín para eliminar todos los índices

Pase un documento de especificación del índice al método dropIndex() para remover un índice de una colección. Un documento de especificación del índice es una instancia de Bson que especifica el tipo de índice en un campo determinado.

El siguiente fragmento elimina un índice ascendente en el campo title de una colección:

moviesCollection.dropIndex(Indexes.ascending(Movie::title.name));

Importante

Si desea eliminar un índice de texto, debe usar su nombre. Consulte la sección "Eliminar un índice mediante un campo de nombre" para obtener más información.

Pase el campo name del índice al método dropIndex() para eliminar un índice de una colección.

Si necesita encontrar el nombre de su índice, utilice el método listIndexes() para ver el valor de los campos name en sus índices.

El siguiente fragmento recupera e imprime todos los índices de una colección:

val indexes = moviesCollection.listIndexes()
indexes.collect { println(it.toJson()) }

Si llama a listIndex() en una colección que contiene un índice de texto, la salida podría parecerse a la siguiente:

{ "v": 2, "key": {"_id": 1}, "name": "_id_" }
{ "v": 2, "key": {"_fts": "text", "_ftsx": 1}, "name": "title_text", "weights": {"title": 1},
"default_language": "english", "language_override": "language", "textIndexVersion": 3 }

Esta salida nos dice que los nombres de los índices existentes son "_id" y "title_text".

El siguiente fragmento elimina el índice "title_text" de la colección:

moviesCollection.dropIndex("title_text")

Nota

No se puede eliminar un solo campo de un índice de texto compuesto. Debe eliminar todo el índice y crear uno nuevo para actualizar los campos indexados.

A partir de MongoDB 4.2, puede eliminar todos los índices llamando al método dropIndexes() en su colección:

moviesCollection.dropIndexes()

Para versiones anteriores de MongoDB, pase "*" como parámetro a su llamada a dropIndex() en su colección:

moviesCollection.dropIndex("*")

Para obtener más información sobre los métodos de esta sección, consulte la siguiente Documentación de la API:

Volver

Intercalaciones