Gestion des index dans Amazon DocumentDB avec Java - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Gestion des index dans Amazon DocumentDB avec Java

Les index permettent de récupérer efficacement les données d'une collection Amazon DocumentDB. Sans index, DocumentDB doit scanner tous les documents de la collection pour renvoyer des résultats répondant à une requête donnée. Cette rubrique fournit des informations sur la façon de créer, supprimer et répertorier des index à l'aide des pilotes Java MongoDB. Il explique également comment déterminer si un index particulier est utilisé dans la requête et comment indiquer à Amazon DocumentDB d'utiliser un index spécifique.

Amazon DocumentDB prend en charge de nombreux types d'index. Pour un aperçu complet de tous les index pris en charge, consultez ce billet de blog.

Création d'index avec Java

Il existe deux mécanismes pour créer des index dans Amazon DocumentDB à l'aide des pilotes Java MongoDB : par le runCommand() biais de createIndex() la méthode pour un index unique ou createIndexes() par la méthode pour plusieurs index. L'une des raisons d'utiliser les createIndexes() méthodes createIndex() et est que vous pouvez améliorer la gestion des erreurs en détectant les erreurs spécifiques liées à la création d'index. Une autre raison d'utiliser ces méthodes runCommand() est que le pilote Java MongoDB fournit un ensemble complet de classes de support pour la création et la manipulation d'index. Notez que ces classes de support ne peuvent être utilisées que lorsque vous utilisez les createIndexes() méthodes createIndex() or. Il existe trois classes de soutien :

  • Indexes— Cette classe est une classe utilitaire proposant des méthodes d'usine statiques pour créer différents types d'index. Il simplifie le processus de création de définitions d'index complexes et est couramment utilisé conjointement avec d'autres classes liées aux indices.

  • IndexModel— Il s'agit d'une classe fondamentale qui encapsule à la fois la définition des clés d'index et ses options. Il représente une spécification d'index complète, combinant les éléments à indexer (les clés) avec la manière d'indexer (les options). Cette classe est particulièrement utile lors de la création simultanée de plusieurs index, car elle permet de définir un ensemble de spécifications d'index qui peuvent être transmises à la createIndexes() méthode.

  • IndexOptions— Il s'agit d'une classe de configuration complète qui fournit un ensemble complet de méthodes pour personnaliser le comportement des index. Il inclut des paramètres pour les index uniques, les index épars, le délai d'expiration (TTL) et les expressions de filtre partielles. Grâce au chaînage de méthodes, vous pouvez configurer plusieurs options telles que la création d'index en arrière-plan et des contraintes uniques.

Création d'un index unique

Cet exemple montre comment créer un index unique à l'aide de la méthodecreateIndex() en arrière-plan. Pour comprendre la création d'index d'arrière-plan et de premier plan, veuillez vous reporter àTypes de construction d'index. L'exemple de code suivant permet IndexOptionsde créer un index unique avec le nom « Unique_RestaurantID_IDX » en arrière-plan. Cet IndexOptions objet est ensuite transmis à la createIndex() méthode.

collection.createIndex( Indexes.ascending("restaurantId"), new IndexOptions() .unique(true) .name("unique_restaurantId_idx") .background(true));

Création de plusieurs index

Cet exemple crée plusieurs index à l'aide de createIndexes() cette méthode. Il crée d'abord l'option pour chaque index en utilisant l'IndexModelobjet, puis transmet une liste d'IndexModelobjets à la createIndexes() méthode. L'exemple de code suivant montre comment créer un index composite à l'aide de la classe Indexesutilitaire. Cette classe est également utilisée pour spécifier si vous souhaitez créer un index en utilisant un ordre de tri croissant ou décroissant. Après avoir créé plusieurs index, il vérifie la création de l'index en appelant la listIndexes() méthode.

// 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()));

Création d'index épars et partiels

Cet exemple montre comment créer un index fragmenté et un index partiel en créant un IndexModelpour chaque type d'index.

// 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))));

Création d'un index de texte

Cet exemple montre comment créer un index de texte. Un seul index de texte est autorisé dans une collection, mais cet index de texte peut être un index composé couvrant plusieurs champs. Lorsque vous utilisez plusieurs champs dans l'index de texte, vous pouvez également attribuer des pondérations à chacun des champs de l'index. Les index de texte sur les champs de tableau ne sont pas pris en charge par Amazon DocumentDB et même si vous pouvez utiliser jusqu'à 30 champs dans l'index de texte composé, seuls trois champs peuvent être pondérés.

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());

Créez un index à l'aide de runCommand()

Amazon DocumentDB prend en charge la création d'index en parallèle afin de réduire le temps nécessaire à la création d'index. L'indexation parallèle utilise plusieurs travailleurs simultanés. Le nombre de travailleurs par défaut utilisés pour la création d'index est de deux. Ce billet de blog fournit une discussion approfondie sur l'indexation parallèle. Actuellement, les pilotes Java MongoDB ne permettent pas de spécifier l'option de travail lorsque vous utilisez createIndex() oucreateIndexes(). Par conséquent, le seul moyen de spécifier les travailleurs est d'utiliser le. runCommand L'exemple de code suivant montre comment runCommand créer un index qui augmente le nombre de travailleurs à quatre :

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);

Suppression d'index

Le pilote Java MongoDB fournit plusieurs méthodes pour supprimer les index, en fonction de différents scénarios et de vos préférences. Vous pouvez supprimer des index par nom, par spécification clé, ou supprimer tous les index en une seule fois. Les méthodes dropIndex() et dropIndexes() peuvent être invoquées sur un objet de collection pour supprimer un index. Lorsque vous supprimez un index par nom, vous devez vous assurer qu'il utilise le nom d'index correct, ce qui n'est pas toujours intuitif, en particulier pour les index composés ou générés automatiquement. Toute tentative de suppression d'un index inexistant se traduira par un MongoCommandException. L'default _idindex ne peut pas être supprimé car il garantit l'unicité du document au sein de la collection.

L'exemple de code suivant montre comment supprimer un index en fournissant le nom du champ dans lequel l'index est créé ou en supprimant tous les index :

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();

Lorsque vous supprimez des index à l'aide de plusieurs clés, assurez-vous qu'il existe un index composé contenant toutes les clés spécifiées et que l'ordre des clés est correct. L'exemple de code de création d'index ci-dessus montre une clé composée sur la « cuisine » et les fonctionnalités. Si vous essayez de supprimer cette clé composée mais que l'ordre ne correspond pas à celui utilisé pour la création, MongoCommnadException l'erreur suivante se produit :

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); }

L'erreur suivante s'affiche :

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

Déterminer la sélection de l'indice et fournir un indice

L'utilisation de la fonctionnalité d'explication d'Amazon DocumentDB est essentielle pour comprendre les performances des requêtes et l'utilisation des index. Lorsque vous exécutez une requête, vous pouvez ajouter la explain() méthode pour obtenir des informations détaillées sur le plan de requête, notamment les index utilisés, le cas échéant. Le explain() résultat fournit des informations sur les étapes d'exécution des requêtes, le nombre de documents examinés et le temps nécessaire à chaque étape. Ces informations sont précieuses pour déterminer si un index particulier est utilisé efficacement ou si la requête pourrait bénéficier d'une structure d'index différente.

Le explain() procédé peut être enchaîné avec le find() procédé. La explain() méthode peut utiliser une ExplainVerbosityénumération facultative qui détermine le niveau de verbosité renvoyé par. explain() Pour le moment, seuls les QUERY_PLANNER énumérateurs EXECUTION_STATS et sont pris en charge par DocumentDB. L'exemple de code suivant montre comment obtenir un planificateur de requêtes pour une requête spécifique :

// 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());

Le document JSON suivant est renvoyé pour le niveau de verbosité du planificateur de requêtes :

{ "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 } } }

Plusieurs options s'offrent à vous pour influencer ou forcer Amazon DocumentDB à utiliser un index spécifique. Les hintString() méthodes hint() et vous permettent de modifier le comportement de sélection d'index par défaut de l'optimiseur de requêtes en spécifiant explicitement quel index doit être utilisé pour une requête. Bien que l'optimiseur de requêtes de DocumentDB fasse généralement de bons choix pour la sélection d'index, il existe des scénarios dans lesquels il hintString() peut être avantageux de forcer hint() ou de forcer un index spécifique, par exemple lorsqu'il s'agit de traiter des données asymétriques ou de tester les performances d'un index.

L'exemple de code suivant force l'utilisation de l'index composé « cuisine_features_idx » pour la même requête que celle exécutée dans le code ci-dessus :

// 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));