Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Indexverwaltung in Amazon DocumentDB mit Java
Indizes ermöglichen das effiziente Abrufen von Daten aus einer Amazon DocumentDB-Sammlung. Ohne Indizes muss DocumentDB jedes Dokument in der Sammlung scannen, um Ergebnisse zurückzugeben, die einer bestimmten Abfrage entsprechen. Dieses Thema enthält Informationen zum Erstellen, Löschen und Auflisten von Indizes mithilfe der MongoDB-Java-Treiber. Außerdem wird erläutert, wie ermittelt werden kann, ob ein bestimmter Index in der Abfrage verwendet wird, und wie Amazon DocumentDB Hinweise zur Verwendung eines bestimmten Indexes gegeben werden kann.
Themen
Amazon DocumentDB unterstützt viele Arten von Indizes. Einen umfassenden Überblick über alle unterstützten Indizes finden Sie in diesem Blogbeitrag.
Indizes mit Java erstellen
Es gibt zwei Mechanismen zum Erstellen von Indizes in Amazon DocumentDB mithilfe von MongoDB-Java-Treibern: durch runCommand()
und entweder durch die createIndex()
Methode für einen einzelnen Index oder durch die createIndexes()
Methode für mehrere Indizes. Ein Grund für die Verwendung der createIndexes()
Methoden createIndex()
und besteht darin, dass Sie eine bessere Fehlerbehandlung aufbauen können, indem Sie bestimmte Fehler im Zusammenhang mit der Indexerstellung abfangen. Ein weiterer Grund für die Verwendung dieser Methode runCommand()
ist, dass der MongDB-Java-Treiber eine Vielzahl von unterstützenden Klassen für die Indexerstellung und -manipulation bereitstellt. Beachten Sie, dass diese unterstützenden Klassen nur verwendet werden können, wenn Sie die Methoden createIndex()
oder createIndexes()
verwenden. Es gibt drei unterstützende Klassen:
Indexes
— Diese Klasse dient als Hilfsklasse und bietet statische Factory-Methoden zur Erstellung verschiedener Arten von Indizes. Sie vereinfacht den Prozess der Erstellung komplexer Indexdefinitionen und wird häufig in Verbindung mit anderen indexbezogenen Klassen verwendet. IndexModel
— Dies ist eine grundlegende Klasse, die sowohl die Definition der Indexschlüssel als auch ihre Optionen kapselt. Sie stellt eine vollständige Indexspezifikation dar, die kombiniert, was indexiert werden soll (die Schlüssel) und wie indexiert werden soll (die Optionen). Diese Klasse ist besonders nützlich, wenn Sie mehrere Indizes gleichzeitig erstellen, da Sie damit eine Sammlung von Indexspezifikationen definieren können, die an die createIndexes()
Methode übergeben werden können.IndexOptions
— Dies ist eine umfassende Konfigurationsklasse, die eine Vielzahl von Methoden zur Anpassung des Indexverhaltens bietet. Sie umfasst Einstellungen für eindeutige Indizes, Sparse-Indizes, Ablaufzeit (TTL) und partielle Filterausdrücke. Durch Methodenverkettung können Sie mehrere Optionen wie die Indexerstellung im Hintergrund und eindeutige Einschränkungen konfigurieren.
Erstellen Sie einen einzelnen Index
Dieses Beispiel zeigt, wie ein einzelner Index mit der Methode createIndex(
() im Hintergrund erstellt wird. Informationen zur Indexerstellung im Hintergrund und Vordergrund finden Sie unterTypen der Indexerstellung. Im folgenden Codebeispiel wird IndexOptions
IndexOptions
Objekt wird dann an die Methode übergeben. createIndex()
collection.createIndex( Indexes.ascending("restaurantId"), new IndexOptions() .unique(true) .name("unique_restaurantId_idx") .background(true));
Erstellen Sie mehrere Indizes
In diesem Beispiel werden mithilfe der Methode mehrere Indizes erstellt. createIndexes()
Es erstellt zuerst die Option für jeden Index mithilfe des IndexModel
IndexModel
Objekten an die createIndexes()
Methode. Das folgende Codebeispiel zeigt, wie ein zusammengesetzter Index mithilfe der Indexes
listIndexes()
// 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()));
Erstellen Sie dünnbesetzte Indizes und partielle Indizes
Dieses Beispiel zeigt, dass ein dünnbesetzter Index und ein partieller Index erstellt werden, indem 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))));
Erstellen Sie einen Textindex
Dieses Beispiel zeigt, wie ein Textindex erstellt wird. In einer Sammlung ist nur ein Textindex zulässig, aber dieser eine Textindex kann ein zusammengesetzter Index sein, der mehrere Felder abdeckt. Wenn Sie mehrere Felder im Textindex verwenden, können Sie auch jedem Feld im Index Gewichtungen zuweisen. Textindizes für Array-Felder werden von Amazon DocumentDB nicht unterstützt, und obwohl Sie bis zu 30 Felder im zusammengesetzten Textindex verwenden können, kann nur drei Feldern eine Gewichtung zugewiesen werden.
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());
Erstellen Sie einen Index mit runCommand()
Amazon DocumentDB unterstützt die parallel Indexerstellung, um den Zeitaufwand für die Erstellung von Indizes zu verringern. Bei der parallelen Indizierung werden mehrere Worker gleichzeitig verwendet. Für die Indexerstellung werden standardmäßig zwei Worker verwendet. Dieser BlogbeitragcreateIndex()
oder createIndexes()
verwenden. Daher können Sie Worker nur über die angeben. runCommand
Das folgende Codebeispiel zeigt, wie Sie runCommand
einen Index erstellen, der den Worker auf vier erhöht:
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);
Indizes löschen
Der MongoDB-Java-Treiber bietet mehrere Methoden zum Löschen von Indizes, die auf unterschiedliche Szenarien und Ihre Präferenzen zugeschnitten sind. Sie können Indizes nach Namen, nach Schlüsselspezifikation oder alle Indizes auf einmal löschen. Die Methoden dropIndex()
und dropIndexes()
können für ein Auflistungsobjekt aufgerufen werden, um einen Index zu löschen. Wenn Sie einen Index nach Namen löschen, sollten Sie sicherstellen, dass der richtige Indexname verwendet wird, was möglicherweise nicht immer intuitiv ist, insbesondere bei zusammengesetzten oder automatisch generierten Indizes. Der Versuch, einen nicht existierenden Index zu löschen, führt zu einem. MongoCommandException
default _id
Index kann nicht gelöscht werden, da er die Einzigartigkeit des Dokuments innerhalb der Sammlung sicherstellt.
Das folgende Codebeispiel zeigt, wie ein Index gelöscht wird, indem der Feldname angegeben wird, in dem der Index erstellt wurde, oder indem alle Indizes gelöscht werden:
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();
Stellen Sie beim Löschen von Indizes mit mehreren Schlüsseln sicher, dass ein zusammengesetzter Index vorhanden ist, der alle angegebenen Schlüssel enthält und dass die Reihenfolge der Schlüssel korrekt ist. Der obige Beispielcode zur Indexerstellung zeigt einen zusammengesetzten Schlüssel für „Küche“ und Funktionen. Wenn Sie versuchen, diesen zusammengesetzten Schlüssel zu löschen, aber die Reihenfolge nicht der Reihenfolge entspricht, in der er erstellt wurde, tritt ein MongoCommnadException Fehler wie folgt auf:
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); }
Der folgende Fehler wird angezeigt:
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
Festlegung der Indexauswahl und Bereitstellung eines Indexhinweises
Die Arbeit mit der Erklärungsfunktion in Amazon DocumentDB ist entscheidend, um die Abfrageleistung und die Indexnutzung zu verstehen. Wenn Sie eine Abfrage ausführen, können Sie die explain()
Methode anhängen, um detaillierte Informationen über den Abfrageplan zu erhalten, einschließlich der verwendeten Indizes. Die explain()
Ausgabe bietet Einblicke in die Phasen der Abfrageausführung, die Anzahl der untersuchten Dokumente und die für jede Phase benötigte Zeit. Diese Informationen sind von unschätzbarem Wert, um festzustellen, ob ein bestimmter Index effektiv verwendet wird oder ob die Abfrage von einer anderen Indexstruktur profitieren könnte.
Die explain()
Methode kann mit der Methode verkettet werden. find()
Die explain()
Methode kann eine optionale ExplainVerbosity
explain()
Derzeit werden nur die QUERY_PLANNER
Enumeratoren EXECUTION_STATS
und von DocumentDB unterstützt. Das folgende Codebeispiel zeigt, wie der Abfrageplaner für eine bestimmte Abfrage abgerufen wird:
// 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());
Das folgende JSON-Dokument wird für die Ausführlichkeitsstufe des Abfrageplaners zurückgegeben:
{
"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
}
}
}
Sie haben mehrere Möglichkeiten, Amazon DocumentDB zu beeinflussen oder zu zwingen, einen bestimmten Index zu verwenden. Mit den hintString()
Methoden hint()
und können Sie das Standardverhalten des Abfrageoptimierers bei der Indexauswahl außer Kraft setzen, indem Sie explizit angeben, welcher Index für eine Abfrage verwendet werden soll. Der Abfrageoptimierer von DocumentDB ist zwar generell eine gute Wahl für die Indexauswahl, es gibt jedoch auch Szenarien, in denen das hint()
Durchsetzen eines bestimmten Indexes von Vorteil sein hintString()
kann, z. B. beim Umgang mit verzerrten Daten oder beim Testen der Indexleistung.
Das folgende Codebeispiel erzwingt die Verwendung des zusammengesetzten Index „cuisine_features_idx“ für dieselbe Abfrage, die im obigen Code ausgeführt wurde:
// 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));