As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Gerenciamento de índices no Amazon DocumentDB com Java
Os índices permitem a recuperação eficiente de dados de uma coleção do Amazon DocumentDB. Sem índices, o DocumentDB deve digitalizar todos os documentos da coleção para retornar resultados que satisfaçam uma determinada consulta. Este tópico fornece informações sobre como criar, eliminar e listar índices usando os drivers de Java do MongoDB. Ele também discute como determinar se um índice específico está sendo usado na consulta e como dar dicas ao Amazon DocumentDB para usar um índice específico.
Tópicos
O Amazon DocumentDB oferece suporte a vários tipos de índices. Para obter uma visão geral abrangente de todos os índices com suporte, consulte esta postagem do blog
Criação de índices com Java
Há dois mecanismos para criar índices no Amazon DocumentDB usando drivers de Java do MongoDB: por meio de runCommand() e pelo método createIndex() para um único índice ou pelo método createIndexes() para vários índices. Um motivo para usar os métodos createIndex() e createIndexes() é que é possível criar um melhor tratamento de erros detectando erros específicos relacionados à criação do índice. Outro motivo para usar esses métodos em vez de runCommand() é que o driver de Java do MongDB fornece um rico conjunto de classes de suporte para criação e manipulação de índices. Observe que essas classes de suporte só poderão ser usadas quando você estiver usando os métodos createIndex() ou createIndexes(). Há três classes de apoio:
Indexes: esta classe serve como uma classe utilitária que oferece métodos estáticos de fábrica para criar vários tipos de índices. Ela simplifica o processo de criação de definições de índice complexas e é comumente usada em conjunto com outras classes relacionadas a índices. IndexModel: esta é uma classe fundamental que encapsula a definição das chaves de índice e suas opções. Ela representa uma especificação completa do índice, combinando o que indexar (as chaves) com a forma de indexar (as opções). Essa classe é particularmente útil ao criar vários índices simultaneamente, pois permite definir uma coleção de especificações de índice que podem ser passadas para o método createIndexes().IndexOptions: esta é uma classe de configuração abrangente que fornece um rico conjunto de métodos para personalizar o comportamento do índice. Ela inclui configurações para índices exclusivos, índices esparsos, tempo de expiração (TTL) e expressões de filtro parcial. Por meio do encadeamento de métodos, é possível configurar várias opções, como a criação de índice em segundo plano e restrições exclusivas.
Criação de um índice único
Este exemplo mostra como criar um índice único usando o método createIndex( em segundo plano. Para entender a criação de índices em segundo plano e em primeiro plano, consulte Tipos de criação de índice. O exemplo de código a seguir usa IndexOptionsIndexOptions é então passado ao método createIndex().
collection.createIndex( Indexes.ascending("restaurantId"), new IndexOptions() .unique(true) .name("unique_restaurantId_idx") .background(true));
Criação de vários índices
Este exemplo cria vários índices usando o método createIndexes(). Primeiro, ele cria a opção para cada índice usando o objeto IndexModelIndexModel para o método createIndexes(). O exemplo de código a seguir mostra como criar um índice composto usando a classe de utilitários IndexeslistIndexes().
// Single Field Index on cuisine IndexModel singleIndex = new IndexModel( Indexes.ascending("cuisine"), new IndexOptions().name("cuisine_idx")); // Compound Index IndexModel compoundIndex = new IndexModel( Indexes.compoundIndex( Indexes.ascending("address.state"), Indexes.ascending("priceRange")), new IndexOptions().name("location_price_idx")); // Build a list of IndexModel for the indexes List < IndexModel > indexes = Arrays.asList( singleIndex, compoundIndex ); collection.createIndexes(indexes); // Verify created indexes collection.listIndexes().forEach(index - > System.out.println("Created index: " + index.toJson()));
Criação de índices esparsos e parciais
Este exemplo mostra a criação de um índice esparso e um parcial com a criação de um IndexModel
// Sparse Index Model, this will identify only those documents that have a // michelin star rating IndexModel sparseIndex = new IndexModel( Indexes.ascending("michelin.star"), new IndexOptions() .name("michelin_sparse_idx") .sparse(true)); // Partial Index Model where the restaurant is active and has a rating of 4 and above IndexModel partialIndex = new IndexModel( Indexes.ascending("rating.average"), new IndexOptions() .name("high_rated_active_idx") .partialFilterExpression( Filters.and( Filters.eq("isActive", true), Filters.gte("rating.average", 4.0))));
Criação de um índice de texto
Este exemplo mostra como criar e excluir um índice de texto. Somente um índice de texto é permitido em uma coleção, mas esse índice de texto pode ser um índice composto cobrindo vários campos. Ao usar vários campos no índice de texto, você também pode atribuir pesos a cada um dos campos no índice. Não há suporte para os índices de texto em campos de matriz no Amazon DocumentDB e, embora você possa usar até 30 campos no índice de texto composto, somente três campos podem receber um peso.
IndexModel textIndex = new IndexModel( new Document() .append("name", "text") .append("description", "text") .append("cuisine", "text"), new IndexOptions() .name("restaurant_text_idx") .weights(new Document() .append("name", 10) // Restaurant name gets highest weight .append("description", 5) // Description get medium weight .append("cuisine", 2) // Cuisine type gets low weight )); collection.createIndex(textIndex.getKeys(), textIndex.getOptions());
Criação de um índice por meio de runCommand()
O Amazon DocumentDB oferece suporte à criação de índices paralelos para diminuir o tempo necessário para criar índices. A indexação paralela usa vários trabalhadores simultâneos. Os trabalhadores padrão usados para a criação do índice são dois. Esta postagem do blogcreateIndex() ou createIndexes() e, portanto, a única maneira de especificar trabalhadores é por meio de runCommand. O exemplo de código a seguir demonstra como usar runCommand para criar um índice que aumente o trabalhador para quatro:
Document command = new Document("createIndexes", "Restaurants") .append("indexes", Arrays.asList( new Document("key", new Document("name", 1)) .append("name", "restaurant_name_idx") .append("workers", 4) // Specify number of workers )); Document commendResult = connectedDB.runCommand(command);
Reduzir índices
O driver de Java do MongoDB fornece vários métodos para eliminar índices, atendendo a diferentes cenários e às suas preferências. É possível eliminar índices por nome, por especificação de chave ou eliminar todos os índices de uma só vez. Os métodos dropIndex() e dropIndexes() podem ser invocados em um objeto de coleção para eliminar um índice. Ao descartar um índice pelo nome, você deverá garantir que eles usem o nome correto, o que nem sempre é intuitivo, especialmente para índices compostos ou gerados automaticamente. A tentativa de eliminar um índice inexistente resultará em uma MongoCommandExceptiondefault _id não pode ser descartado, pois garante a exclusividade do documento na coleção.
O exemplo de código a seguir mostra como eliminar um índice fornecendo o nome do campo em que o índice foi criado ou excluindo todos os índices:
String indexName = "unique_restaurantId_idx"; Document keys = new Document("cuisine", 1); // Drop index by name collection.dropIndex(indexName); // Drop index by keys collection.dropIndex(keys); // Drop all indexes collection.dropIndexes();
Ao descartar índices usando várias chaves, verifique se há um índice composto contendo todas as chaves especificadas e se a ordem das chaves está correta. O código de exemplo de criação de índice acima mostra uma chave composta sobre “culinária” e recursos. Se você tentar eliminar essa chave composta, mas a ordem não for a usada para a criação, ocorrerá um MongoCommnadException erro da seguinte forma:
Document keys = new Document("features", 1) .append("cuisine", 1); try { // Drop index by keys collection.dropIndex(keys); System.out.println("Successfully dropped index with keys: " + keys.toJson()); } catch (MongoCommandException commErr) { System.out.println("Error dropping index: " + commErr.getErrorMessage()); throw new RuntimeException("MongoCommandException was thrown while dropping index", commErr); }
O seguinte erro é exibido:
Error dropping index: Cannot drop index: index not found.
Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.819 sec <<< FAILURE!
com.amazon.docdb.guide.DocDBGuideTest.testindexGuide() Time elapsed: 0.817 sec <<< FAILURE!
org.opentest4j.AssertionFailedError: Unexpected exception thrown: java.lang.RuntimeException: MongoCommandException was thrown while dropping index
Determinação da seleção do índice e fornecimento de dicas de índice
O trabalho com a funcionalidade de explicação no Amazon DocumentDB é fundamental para que você entenda a performance das consultas e o uso de índices. Ao executar uma consulta, é possível acrescentar o método explain() para obter informações detalhadas sobre o plano da consulta, incluindo quais índices, se houver, estão sendo usados. O resultado explain() fornece informações sobre os estágios de execução da consulta, o número de documentos examinados e o tempo gasto em cada estágio. Essas informações são inestimáveis para identificar se um determinado índice está sendo usado de forma eficaz ou se a consulta pode se beneficiar de uma estrutura de índices diferente.
O método explain() pode ser encadeado com o método find(). O método explain() pode usar uma enumeração ExplainVerbosityexplain(). No momento, há suporte somente aos enumeradores EXECUTION_STATS e QUERY_PLANNER no DocumentDB. O exemplo de código a seguir mostra como obter um planejador de consultas para uma consulta específica:
// Query we want to analyze Document query = new Document() .append("cuisine", "Thai") .append("rating.average", new Document("$gte", 4.0)); Document allPlansExplain = collection.find(query).explain(ExplainVerbosity.QUERY_PLANNER); System.out.println("All Plans Explain:\n" + allPlansExplain.toJson());
O documento JSON a seguir é retornado para o nível de verbosidade do planejador de consultas:
{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "ProgGuideData.Restaurants",
"winningPlan": {
"stage": "IXSCAN",
"indexName": "cuisine_idx",
"direction": "forward"
}
},
"serverInfo": {
"host": "guidecluster3",
"port": 27017,
"version": "5.0.0"
},
"ok": 1,
"operationTime": {
"$timestamp": {
"t": 1739221668,
"i": 1
}
}
}
Você tem várias opções para influenciar ou forçar o Amazon DocumentDB a usar um índice específico. Os métodos hint() e hintString() permitem que você substitua o comportamento padrão de seleção de índice do otimizador de consultas especificando explicitamente qual índice deve ser usado para uma consulta. Embora o otimizador de consultas do DocumentDB geralmente faça boas escolhas para a seleção de índices, há cenários em que forçar a aprovação de um índice específico por meio de hint() ou hintString() pode ser benéfico, como ao lidar com dados distorcidos ou ao testar a performance do índice.
O exemplo de código a seguir força o uso do índice composto “cuisine_features_idx” para a mesma consulta que foi executada no código acima:
// Query we want to analyze Document query = new Document() .append("cuisine", "Thai") .append("rating.average", new Document("$gte", 4.0)); List < Document > queryDocs = new ArrayList < > (); collection.find(query).hintString("cuisine_features_idx").forEach(doc - > queryDocs.add(doc));