Indexes
Nesta página
- Visão geral
- Cobertura e desempenho da query
- Considerações operacionais
- Tipos de índice
- Campo único e índices compostos
- Índices de várias teclas (índices em campos de array)
- Atlas Search e índices de Vector Search
- Text Indexes
- Índices geoespaciais
- Unique Indexes
- Índices aglomerados
- Remover um Índice
- Remover um Índice usando um Documento de Especificação do Índice
- Remover um índice usando um campo de nome
- Remover um índice usando um caractere curinga
Visão geral
Neste guia, você pode aprender como criar e managed índices usando o MongoDB Kotlin Driver.
Os índices suportam a execução eficiente de query no MongoDB. Sem índices, o MongoDB deve verificar todos os documentos de uma collection ( uma varredura de collection ) para encontrar os documentos que correspondem a cada query. Essas verificações da collection são lentas e podem afetar negativamente o desempenho do seu aplicativo. Se existir um índice apropriado para uma query, o MongoDB poderá usar o índice para limitar os documentos que a query deve inspecionar.
Os índices também têm os seguintes benefícios:
Os índices permitem uma classificação eficiente.
Os índices habilitam capacidades especiais, comoqueries geoespaciaisdo .
Os índices permitem a criação de restrições para garantir que um valor de campo seja exclusivo.
Para saber mais, consulte Índices no manual do servidor.
Dica
As operações de atualização usam índices ao localizar documentos para atualizar, e as operações de exclusão usam índices ao localizar documentos para excluir. Determinados estágios do aggregation pipeline também usam índices para melhorar o desempenho.
Cobertura e desempenho da query
Quando você executa uma query no MongoDB, seu comando pode incluir vários elementos:
Critérios de query que especificam campos e valores que você está procurando
Opções que afetam a execução da query, como a referência de leitura
Critérios de projeção para especificar os campos retornos MongoDB (opcional)
Classificar critérios para especificar a ordem dos documentos devolvidos do MongoDB (opcional)
Quando todos os campos especificados na query, projeção e classificação encontram-se no mesmo índice, o MongoDB gera resultados diretamente do índice, também chamado de query coberta.
Importante
Ordem de classificação
Os critérios de classificação devem corresponder ou inverter a ordem do índice.
Considere um índice no campo name
em ordem crescente (A-Z) e age
em ordem decrescente (9-0):
name_1_age_-1
O MongoDB usa esse índice quando você classifica seus dados de uma das seguintes maneiras:
name
ascendente, descendenteage
name
descendente, ascendenteage
Especificar uma ordem de classificação de name
e age crescente ou name e age
decrescente requer uma classificação na memória.
Para obter mais informações sobre como garantir que seu índice cubra seus critérios de query e projeção, consulte os artigos do manual do servidor MongoDB sobre cobertura de query.
Considerações operacionais
As diretrizes a seguir descrevem como você pode otimizar a forma como seu aplicativo usa índices:
Para melhorar o desempenho da query, crie índices em campos que aparecem com frequência nas queries e operações do seu aplicativo que retornam resultados ordenados.
Acompanhe a memória do índice e o uso do disco para o planejamento da capacidade, pois cada índice adicionado consome espaço em disco e memória quando ativo.
Evite adicionar índices que você usa com pouca frequência. Observe que quando uma operação de gravação atualiza um campo indexado, o MongoDB atualiza o índice relacionado.
Como o MongoDB oferece suporte a esquemas dinâmicos, os aplicativos podem executar a query dos campos cujos nomes não podem ser conhecidos antecipadamente ou são arbitrários. O MongoDB 4.2 introduziu índices curinga para ajudar a suportar essas queries. Os índices curinga não são projetados para substituir o planejamento de índice baseado em carga de trabalho.
Para obter mais informações sobre como projetar seu modelo de dados e escolher índices apropriados para seu aplicativo, consulte a documentação do servidor MongoDB sobre Estratégias de indexação e Modelagem de dados e índices.
Tipos de índice
O MongoDB suporta vários tipos de índice diferentes para auxiliar na consulta de seus dados. As seções a seguir descrevem os tipos de índice mais comuns e fornecem código de amostra para criar cada tipo de índice. Para obter uma lista completa dos tipos de índice, consulte Índices no manual do servidor MongoDB.
Dica
O driver Kotlin fornece os Índices classe para criar e gerenciar índices. Esta classe inclui métodos de fábrica estáticos para criar documentos de especificação de índice para diferentes tipos de chave de índice MongoDB.
Os exemplos a seguir usam o método createIndex() para criar vários índices e as seguintes classes de dados para modelar dados no 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 ) } }
Campo único e índices compostos
Índices de campo único
Os índices de campo único são índices com uma referência a um único campo dentro dos documentos de uma coleção. Eles melhoram o desempenho da consulta de campo único e da classificação e oferecem suporte a índices TTL que removem automaticamente documentos de uma coleção após um determinado período de tempo ou em um horário específico.
Observação
O índice _id_
é um exemplo de um único índice de campo. Este índice é criado automaticamente no campo _id
quando uma nova coleção é criada.
O exemplo a seguir cria um índice em ordem crescente no campo title
:
val resultCreateIndex = moviesCollection.createIndex(Indexes.ascending(Movie::title.name)) println("Index created: $resultCreateIndex")
Index created: title_1
A seguir, um exemplo de uma query coberta pelo índice criado no trecho 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) }
Consulte a seção manual do servidor MongoDB em índices de campo único para obter mais informações.
Índices compostos
Os índices compostos contêm referências a vários campos nos documentos de uma coleção, melhorando o desempenho de consulta e classificação.
Dica
Leia mais sobre índices compostos, prefixos de índice e ordem de classificação aqui.
O exemplo seguinte cria um índice composto nos campos type
e rated
:
val resultCreateIndex = moviesCollection.createIndex(Indexes.ascending(Movie::type.name, Movie::rated.name)) println("Index created: $resultCreateIndex")
Index created: type_1_rated_1
A seguir, um exemplo de uma query coberta pelo índice criado no trecho 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 a seção manual do servidor MongoDB em Índices compostos para obter mais informações.
Índices de várias teclas (índices em campos de array)
Os índices de várias chaves são índices que melhoram o desempenho de queries que especificam um campo com um índice que contém um valor de array. Você pode definir um índice de múltiplas chaves utilizando a mesma sintaxe de um único campo ou índice composto.
O exemplo a seguir cria um índice composto de várias chaves nos campos rated
, genres
(uma array de Strings) e 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
A seguir, um exemplo de uma query coberta pelo índice criado no trecho 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) }
Os índices multicamadas se comportam de forma diferente de outros índices em termos de cobertura de consulta, computação vinculada a índice e comportamento de classificação. Para saber mais sobre índices de várias chaves, incluindo uma discussão sobre seu comportamento e limitações, consulte Índices de várias chaves no manual do servidor MongoDB.
Atlas Search e índices de Vector Search
Você pode gerenciar programaticamente seus índices Atlas Search e Atlas Vector Search usando o driver Kotlin .
O recurso Atlas Search permite realizar pesquisas de texto completo em collections hospedadas no MongoDB Atlas. Para saber mais sobre o MongoDB Atlas Search, consulte a documentação dos índices do Atlas Search.
O Atlas Vector Search permite realizar pesquisas semânticas em incorporações vetoriais armazenadas no MongoDB Atlas. Para saber mais sobre o Atlas Vector Search, consulte a seção doAtlas Vector Search no guia do Aggregates Builder.
Você pode chamar os seguintes métodos em uma coleção para gerenciar seus índices Atlas Search e Vector Search :
createSearchIndex()
(válido somente para índices de pesquisa)createSearchIndexes()
listSearchIndexes()
updateSearchIndex()
dropSearchIndex()
Observação
Os métodos de gerenciamento do índice de pesquisa do Atlas Search são executados de forma assíncrona. Os métodos do driver podem ser gerados antes de confirmar que foram executados corretamente. Para determinar o status atual dos índices, chame o método listSearchIndexes()
.
As seções a seguir fornecem exemplos de código que demonstram como usar cada um dos métodos anteriores.
Criar um índice de pesquisa
Você pode utilizar o método createSearchIndex() para criar um único índice de Atlas Search . Você não pode utilizar este método para criar um índice de Vector Search .
Você pode utilizar o método createSearchIndexes() para criar múltiplos índices do Atlas Search ou Vector Search . Você deve criar uma instância SearchIndexModel para cada índice e, em seguida, passar uma lista de SearchIndexModel
instâncias para o createSearchIndexes()
método.
O seguinte exemplo de código mostra como criar um índice Atlas Search:
val searchIdx = Document( "mappings", Document("dynamic", true) ) val resultCreateIndex = moviesCollection.createSearchIndex("myIndex", searchIdx)
Para criar vários índices de pesquisa ou pesquisa Vector Search , você deve criar um SearchIndexModel instância para cada índice.
O exemplo de código a seguir mostra como criar índices de pesquisa e Vector Search em uma chamada:
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) )
Listar índices de pesquisa
Você pode usar o listSearchIndexes() para retornar uma lista dos índices do Atlas Search em uma coleção.
O seguinte exemplo de código mostra como imprimir uma lista do índice de pesquisa em uma collection:
val searchIndexesList = moviesCollection.listSearchIndexes().toList()
Atualizar um Índice de Pesquisa
Você pode utilizar o método updateSearchIndex() para atualizar um índice do Atlas Search.
O seguinte código mostra como atualizar um índice de pesquisa:
moviesCollection.updateSearchIndex( "myIndex", Document("analyzer", "lucene.simple").append( "mappings", Document("dynamic", false) .append( "fields", Document( "title", Document("type", "string") ) ) ) )
Eliminar um Índice de Pesquisa
Você pode utilizar o método dropSearchIndex() para remover um índice do Atlas Search.
O seguinte código mostra como excluir um índice de pesquisa de uma coleção:
moviesCollection.dropSearchIndex("myIndex");
Text Indexes
Os índices de texto suportam queries de pesquisa de texto no conteúdo de string. Esses índices podem incluir qualquer campo cujo valor seja uma string ou uma array de elementos de string. O MongoDB suporta pesquisa de texto para vários idiomas. Você pode especificar o idioma padrão como uma opção ao criar o índice.
Dica
O MongoDB oferece uma solução aprimorada de pesquisa de texto completo, o Atlas Search. Para saber mais sobre os índices do Atlas Search e como usá-los, consulte a seção Índices do Atlas Search e Vector Search deste guia.
Campo Único
O exemplo seguinte cria um índice de texto no 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
O seguinte é um exemplo de uma query coberta pelo índice criado no trecho de código anterior. Observe que o sort
é omitido porque os índices de texto não contêm ordem de classificação.
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) }
Vários campos
Uma coleção só pode conter um índice de texto. Se você deseja criar um índice de texto para múltiplos campos de texto, você deve criar um índice composto. Uma pesquisa de texto é executada em todos os campos de texto dentro do índice composto.
O seguinte trecho cria um índice de texto composto para os campos title
e 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 obter mais informações, consulte as seguintes entradas manuais do servidor:
Índices geoespaciais
O MongoDB suporta queries de dados de coordenadas geoespaciais utilizando índices dsphere do2. Com um índice 2dsphere
, você pode executar query dos dados geoespaciais para inclusão, interseção e proximidade. Para mais informações sobre query de dados geoespaciais, consulte queries geoespaciais no manual do servidor MongoDB.
Para criar um índice do 2dsphere
, você deve especificar um campo que contém somente Objetos GeoJSON. Para saber mais sobre este tipo, consulte ObjetosGeoJSON no manual do servidor MongoDB.
O campo location.geo
no seguinte documento de amostra da coleção theaters
no banco de dados sample_mflix
é um objeto de ponto GeoJSON que descreve as coordenadas do 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 ] } } }
O seguinte exemplo cria um índice 2dsphere
no 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
Tentar criar um índice geoespacial em um campo que já está coberto por um índice geoespacial resulta em um erro.
O seguinte é um exemplo de uma query geoespacial que é coberta pelo índice criado no trecho 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) }
O MongoDB também suporta índices 2d
para calcular distâncias em um plano euclidiano e para trabalhar com a sintaxe dos "legacy coordinate pairs" usada no MongoDB 2.2 e anteriores. Para saber mais, consulte Queries geoespaciais no manual do servidor MongoDB.
Unique Indexes
Índices únicos garantem que os campos indexados não armazenem valores duplicados. Por padrão, o MongoDB cria um índice único no campo _id
durante a criação de uma collection. Para criar um índice único, especifique o campo ou a combinação de campos em que você deseja evitar a duplicação e defina a opção unique
para true
.
O exemplo seguinte cria um índice descendente único no 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
Se você executar uma operação de gravação que armazena um valor duplicado que viola o índice único, o driver gera um DuplicateKeyException
e o MongoDB lança um erro semelhante ao seguinte:
E11000 duplicate key error index
Consulte a página Índices únicos no manual do servidor MongoDB para obter mais informações.
Índices aglomerados
Os índices de cluster instruem a collection a armazenar documentos ordenados por um valor de chave. Para criar um índice de cluster, especifique a opção de índice de cluster com o campo _id
como a chave e o campo único como true
ao criar a collection.
O exemplo seguinte cria um índice agrupado no campo _id
na coleção vendors
:
val clusteredIndexOptions = ClusteredIndexOptions(Document("_id", 1), true) val createCollectionOptions = CreateCollectionOptions().clusteredIndexOptions(clusteredIndexOptions) database.createCollection("vendors", createCollectionOptions)
Consulte as seções manuais do servidor MongoDB para obter mais informações:
Remover um Índice
Você pode remover qualquer índice não utilizado, exceto o índice exclusivo padrão no campo _id
.
As seções a seguir mostram as maneiras de remover índices:
Usando um documento de especificação de índice
Usando um campo de nome indexado
Usando um caractere curinga para remover todos os índices
Remover um Índice usando um Documento de Especificação do Índice
Passe um documento de especificação de índice para o método dropIndex()
para remover um índice de uma coleção. Um documento de especificação de índice é uma instância do Bson
que especifica o tipo de índice em um campo especificado.
O seguinte trecho remove um índice ascendente no campo title
em uma coleção:
moviesCollection.dropIndex(Indexes.ascending(Movie::title.name));
Importante
Se você deseja descartar um índice de texto, você deve utilizar o nome do índice. Consulte a seção Remover um índice usando um campo de nome para obter detalhes.
Remover um índice usando um campo de nome
Passe o campo name
do índice para o método dropIndex()
para remover um índice de uma coleção.
Se você precisar encontrar o nome do seu índice, utilize o método listIndexes()
para visualizar o valor dos campos name
em seus índices.
O trecho a seguir recupera e imprime todos os índices em uma coleção:
val indexes = moviesCollection.listIndexes() indexes.collect { println(it.toJson()) }
Se você chamar listIndex()
em uma coleção que contém um índice de texto, a saída poderá se assemelhar ao seguinte:
{ "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 }
Essa saída nos informa que os nomes dos índices existentes são "_id" e "title_text".
O trecho a seguir remove o índice "title_text" da coleção:
moviesCollection.dropIndex("title_text")
Observação
Não é possível remover um único campo de um índice de texto composto. Você deve soltar o índice inteiro e criar um novo para atualizar os campos indexados.
Remover um índice usando um caractere curinga
A partir do MongoDB 4.2, você pode soltar todos os índices ligando para o método dropIndexes()
em sua coleção:
moviesCollection.dropIndexes()
Para versões anteriores do MongoDB, passe "*" como parâmetro para sua chamada para dropIndex()
em sua coleção:
moviesCollection.dropIndex("*")
Para obter mais informações sobre os métodos nesta seção, consulte a seguinte documentação da API: