View a markdown version of this page

Gestione degli indici in Amazon DocumentDB con Java - Amazon DocumentDB

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Gestione degli indici in Amazon DocumentDB con Java

Gli indici consentono un recupero efficiente dei dati da una raccolta Amazon DocumentDB. Senza indici, DocumentDB deve scansionare tutti i documenti della raccolta per restituire risultati che soddisfino una determinata query. Questo argomento fornisce informazioni su come creare, eliminare ed elencare gli indici utilizzando i driver Java MongoDB. Viene inoltre descritto come determinare se un determinato indice viene utilizzato nella query e come fornire suggerimenti ad Amazon DocumentDB per utilizzare un indice specifico.

Amazon DocumentDB supporta molti tipi di indici. Per una panoramica completa di tutti gli indici supportati, consulta Come indicizzare su Amazon DocumentDB nel blog del database. AWS

Creazione di indici con Java

Esistono due meccanismi per creare indici in Amazon DocumentDB utilizzando i driver Java MongoDB: tramite e tramite runCommand() il createIndex() metodo per un singolo indice o il metodo per più indici. createIndexes() Uno dei motivi per utilizzare i createIndexes() metodi createIndex() and è che puoi migliorare la gestione degli errori rilevando errori specifici relativi alla creazione dell'indice. Un altro motivo per utilizzare questi metodi runCommand() è che il driver Java MongDB fornisce un ricco set di classi di supporto per la creazione e la manipolazione degli indici. Nota che queste classi di supporto possono essere utilizzate solo quando si utilizzano i createIndex() metodi or. createIndexes() Esistono tre classi di supporto:

  • Indexes— Questa classe funge da classe di utilità che offre metodi di fabbrica statici per la creazione di vari tipi di indici. Semplifica il processo di creazione di definizioni di indici complesse ed è comunemente usata insieme ad altre classi relative agli indici.

  • IndexModel— Questa è una classe fondamentale che racchiude sia la definizione delle chiavi dell'indice che le relative opzioni. Rappresenta una specifica completa dell'indice, che combina cosa indicizzare (le chiavi) con come indicizzare (le opzioni). Questa classe è particolarmente utile quando si creano più indici contemporaneamente, in quanto consente di definire una raccolta di specifiche di indice che possono essere passate al createIndexes() metodo.

  • IndexOptions— Questa è una classe di configurazione completa che fornisce un ricco set di metodi per personalizzare il comportamento degli indici. Include impostazioni per indici univoci, indici sparsi, tempo di scadenza (TTL) ed espressioni di filtro parziali. Tramite il concatenamento di metodi, è possibile configurare più opzioni come la creazione di indici in background e vincoli univoci.

Crea un indice singolo

Questo esempio mostra come creare un indice singolo utilizzando il metodocreateIndex() in background. Per informazioni sulla creazione di indici in background e in primo piano, fare riferimento a. Tipi di compilazione dell'indice Il seguente esempio di codice viene utilizzato IndexOptions per creare un indice univoco con il nome «unique_restaurantId_idx» in background. Questo IndexOptions oggetto viene quindi passato al metodo. createIndex()

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

Crea più indici

Questo esempio crea più indici utilizzando il metodo. createIndexes() Per prima cosa crea l'opzione per ogni indice utilizzando l'IndexModeloggetto e quindi passa un elenco di IndexModel oggetti al metodo. createIndexes() L'esempio di codice seguente mostra come creare un indice composito utilizzando la classe di Indexes utilità. Questa classe viene utilizzata anche per specificare se si desidera creare un indice utilizzando un ordinamento crescente o decrescente. Dopo aver creato più indici, verifica la creazione dell'indice chiamando il metodo. 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()));

Crea indici sparsi e parziali

Questo esempio mostra la creazione di un indice sparso e parziale creando un indice IndexModel per ogni tipo di indice.

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

Crea un indice di testo

Questo esempio mostra come creare un indice di testo. In una raccolta è consentito un solo indice di testo, ma tale indice di testo può essere un indice composto che copre più campi. Quando si utilizzano più campi nell'indice di testo, è anche possibile assegnare pesi a ciascuno dei campi dell'indice. Gli indici di testo sui campi di matrice non sono supportati da Amazon DocumentDB e anche se è possibile utilizzare fino a 30 campi nell'indice di testo composto, è possibile assegnare un peso solo a tre campi.

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

Crea un indice usando runCommand()

Amazon DocumentDB supporta la creazione parallela di indici per ridurre il tempo necessario per la creazione degli indici. L'indicizzazione parallela utilizza più lavoratori simultanei. I worker predefiniti utilizzati per la creazione dell'indice sono due. Per ulteriori informazioni, consulta Unlock the power of parallel indexing in Amazon DocumentDB nel Database Blog. AWS Attualmente, i driver Java MongDB non supportano la specificazione dell'opzione worker quando si utilizza createIndex() or createIndexes() e quindi l'unico modo per specificare i worker è tramite. runCommand Il seguente esempio di codice dimostra come utilizzare per runCommand creare un indice che aumenti il lavoratore a quattro:

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

Eliminazione degli indici

Il driver Java MongoDB offre diversi metodi per eliminare gli indici, adattandosi a diversi scenari e preferenze. Puoi eliminare gli indici per nome, per specifica della chiave o eliminare tutti gli indici contemporaneamente. I metodi dropIndex() dropIndexes() possono essere richiamati su un oggetto di raccolta per eliminare un indice. Quando si elimina un indice per nome, è necessario assicurarsi che utilizzino il nome di indice corretto, il che potrebbe non essere sempre intuitivo, specialmente per gli indici composti o generati automaticamente. Il tentativo di eliminare un indice inesistente comporterà un. MongoCommandException L'default _idindice non può essere eliminato poiché garantisce l'unicità del documento all'interno della raccolta.

L'esempio di codice seguente mostra come eliminare un indice fornendo il nome del campo in cui viene creato l'indice o eliminando tutti gli indici:

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

Quando si eliminano gli indici utilizzando più chiavi, assicurati che sia presente un indice composto contenente tutte le chiavi specificate e che l'ordine delle chiavi sia corretto. Il codice di esempio di creazione dell'indice riportato sopra mostra una chiave composta su «cucina» e caratteristiche. Se si tenta di eliminare quella chiave composta ma l'ordine non è quello utilizzato per la creazione, si verifica un MongoCommnadException errore come segue:

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

Viene visualizzato l'errore seguente:

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

Determinazione della selezione dell'indice e fornitura di un suggerimento sull'indice

Utilizzare la funzionalità di spiegazione di Amazon DocumentDB è fondamentale per comprendere le prestazioni delle query e l'utilizzo degli indici. Quando si esegue una query, è possibile aggiungere il explain() metodo per ottenere informazioni dettagliate sul piano di query, inclusi gli eventuali indici utilizzati. L'explain()output fornisce informazioni dettagliate sulle fasi di esecuzione della query, sul numero di documenti esaminati e sul tempo impiegato per ciascuna fase. Queste informazioni sono preziose per identificare se un determinato indice viene utilizzato in modo efficace o se la query potrebbe trarre vantaggio da una diversa struttura dell'indice.

Il explain() metodo può essere concatenato al find() metodo. Il explain() metodo può accettare un'ExplainVerbosityenumerazione opzionale che determina il livello di verbosità restituito da. explain() Al momento, solo gli QUERY_PLANNER enumeratori EXECUTION_STATS e sono supportati da DocumentDB. Il seguente esempio di codice mostra come ottenere Query Planner per una query specifica:

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

Il seguente documento JSON viene restituito per il livello di verbosità del Query Planner:

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

Sono disponibili diverse opzioni per influenzare o forzare Amazon DocumentDB a utilizzare un indice specifico. hintString()I metodi hint() and consentono di sovrascrivere il comportamento di selezione dell'indice predefinito di Query Optimizer specificando esplicitamente quale indice deve essere utilizzato per una query. Sebbene l'ottimizzatore di query di DocumentDB sia generalmente una buona scelta per la selezione dell'indice, ci sono scenari in cui forzare hint() o hintString() può essere utile forzare un indice specifico, ad esempio quando si hanno a che fare con dati distorti o si testano le prestazioni dell'indice.

Il seguente esempio di codice impone l'uso dell'indice composto «cuisine_features_idx» per la stessa query eseguita nel codice precedente:

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