

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à.

# Esecuzione di operazioni CRUD in Amazon DocumentDB con Java
<a name="java-crud-operations"></a>

Questa sezione descrive l'esecuzione dell'operazione CRUD (creazione, lettura, aggiornamento, eliminazione) in Amazon DocumentDB utilizzando i driver Java MongoDB.

**Topics**
+ [Creazione e inserimento di documenti in una raccolta DocumentDB](#creating-inserting)
+ [Lettura e recupero di dati da una raccolta DocumentDB](#reading-retrieving)
+ [Aggiornamento di documenti esistenti in una raccolta DocumentDB](#updating-documents)
+ [Rimuovere documenti da una raccolta DocumentDB](#deleting-documents)
+ [Gestione degli errori con la logica di ripetizione](#error-handling)

## Creazione e inserimento di documenti in una raccolta DocumentDB
<a name="creating-inserting"></a>

L'inserimento di documenti in Amazon DocumentDB ti consente di aggiungere nuovi dati alle tue raccolte. Esistono diversi modi per eseguire gli inserimenti, a seconda delle esigenze e del volume di dati con cui stai lavorando. Il metodo più semplice per inserire un singolo documento nella raccolta è. `insertOne()` Per inserire più documenti contemporaneamente, è possibile utilizzare il `insertMany()` metodo, che consente di aggiungere una serie di documenti in un'unica operazione. Un altro metodo per inserire molti documenti in una raccolta DocumentDB è. `bulkWrite()` In questa guida, discutiamo tutti questi metodi per creare documenti in una raccolta DocumentDB.

**`insertOne()`**

Iniziamo esaminando come inserire un singolo documento in una raccolta Amazon DocumentDBB. L'inserimento di un singolo documento viene eseguito utilizzando il metodo. `insertOne()` Questo metodo richiede un [BsonDocument](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/bson/org/bson/BsonDocument.html)per l'inserimento e restituisce un [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/InsertOneResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/InsertOneResult.html)oggetto che può essere utilizzato per ottenere l'id dell'oggetto del nuovo documento inserito. Il codice di esempio seguente mostra l'inserimento di un documento relativo a un ristorante nella raccolta:

```
Document article = new Document()
    .append("restaurantId", "REST-21G145")
    .append("name", "Future-proofed Intelligent Bronze Hat")
    .append("cuisine", "International")
    .append("rating", new Document()
        .append("average", 1.8)
        .append("totalReviews", 267))
    .append("features", Arrays.asList("Outdoor Seating", "Live Music"));

try {
    InsertOneResult result = collection.insertOne(article);
    System.out.println("Inserted document with the following id: " + result.getInsertedId());
} catch (MongoWriteException e) {
    // Handle duplicate key or other write errors
    System.err.println("Failed to insert document: " + e.getMessage());
    throw e;
} catch (MongoException e) {
    // Handle other MongoDB errors
    System.err.println("MongoDB error: " + e.getMessage());
    throw e;
}
```

Durante l'utilizzo`insertOne()`, assicuratevi di includere una gestione degli errori appropriata. Ad esempio, nel codice precedente, «`restaurantId`» ha un indice univoco e quindi eseguendo nuovamente questo codice si genererà quanto segue`MongoWriteException`:

```
Failed to insert document: Write operation error on server docdbCluster.docdb.amazonaws.com:27017. 
Write error: WriteError{code=11000, message='E11000 duplicate key error collection: Restaurants index: restaurantId_1', details={}}.
```

**insertMany ()**

I metodi principali utilizzati per inserire molti documenti in una raccolta sono insertMany () e. `bulkWrite()` 

Il `insertMany()` metodo è il modo più semplice per inserire più documenti in un'unica operazione. Accetta un elenco di documenti e li inserisce nella raccolta. Questo metodo è ideale quando si inserisce un batch di nuovi documenti indipendenti l'uno dall'altro e che non richiedono alcuna elaborazione speciale o operazioni miste. Il codice seguente mostra la lettura di documenti JSON da un file e il loro inserimento nella raccolta. La `insertMany()` funzione restituisce un [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/InsertManyResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/InsertManyResult.html)`InsertManyResult`oggetto che può essere utilizzato per ottenere tutti IDs i documenti inseriti.

```
// Read JSON file content
String content = new String(Files.readAllBytes(Paths.get(jsonFileName)));
JSONArray jsonArray = new JSONArray(content);

// Convert JSON articles to Documents
List < Document > restaurants = new ArrayList < > ();
for (int i = 0; i < jsonArray.length(); i++) {
    JSONObject jsonObject = jsonArray.getJSONObject(i);
    Document doc = Document.parse(jsonObject.toString());
    restaurants.add(doc);
}
//insert documents in collection
InsertManyResult result = collection.insertMany(restaurants);

System.out.println("Count of inserted documents: " + result.getInsertedIds().size());
```

**[https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/package-summary.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/package-summary.html)**

Il `bulkWrite()` metodo consente di eseguire più operazioni di scrittura (inserimento, aggiornamento, eliminazione) in un unico batch. È possibile utilizzarlo `bulkWrite()` quando è necessario eseguire diversi tipi di operazioni in un unico batch, come l'inserimento di alcuni documenti e l'aggiornamento di altri. `bulkWrite()`supporta due tipi di scrittura in batch, ordinata e non ordinata:
+ *Operazioni ordinate*: (impostazione predefinita) Amazon DocumentDB elabora le operazioni di scrittura in sequenza e si interrompe al primo errore riscontrato. Ciò è utile quando l'ordine delle operazioni è importante, ad esempio quando le operazioni successive dipendono da quelle precedenti. Tuttavia, le operazioni ordinate sono generalmente più lente delle operazioni non ordinate. Con le operazioni ordinate, è necessario risolvere il caso in cui il batch si interrompa al primo errore, lasciando potenzialmente alcune operazioni non elaborate.
+ *Operazioni non ordinate*: consente ad Amazon DocumentDB di elaborare gli inserti come un'unica esecuzione nel database. Se si verifica un errore con un documento, l'operazione continua con i documenti rimanenti. Ciò è particolarmente utile quando si inseriscono grandi quantità di dati e può tollerare alcuni errori, ad esempio durante la migrazione dei dati o le importazioni di massa, in cui alcuni documenti potrebbero non riuscire a causa di chiavi duplicate. Nel caso di operazioni non ordinate, è necessario affrontare scenari di successo parziale in cui alcune operazioni hanno successo mentre altre falliscono.

Quando si utilizza il `bulkWrite()` metodo, sono necessarie alcune classi essenziali. Innanzitutto, la [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/WriteModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/WriteModel.html)classe funge da classe base per tutte le operazioni di scrittura e con implementazioni specifiche come [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/InsertOneModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/InsertOneModel.html),, [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/UpdateOneModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/UpdateOneModel.html), e la [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/DeleteManyModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/DeleteManyModel.html)gestione di diversi tipi di operazioni.

La [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/BulkWriteOptions.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/BulkWriteOptions.html)classe è necessaria per configurare il comportamento delle operazioni di massa, come impostare l' ordered/unordered esecuzione o ignorare la convalida dei documenti. La [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteResult.html)classe fornisce informazioni dettagliate sui risultati dell'esecuzione, incluso il conteggio dei documenti inseriti, aggiornati ed eliminati.

Per la gestione degli errori, la [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoBulkWriteException.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoBulkWriteException.html)classe è fondamentale in quanto contiene informazioni su eventuali errori durante l'operazione in blocco, mentre la [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteError.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteError.html)classe fornisce dettagli specifici sugli errori delle singole operazioni. Il codice seguente mostra un esempio di inserimento di un elenco di documenti, nonché di aggiornamento ed eliminazione di un singolo documento, il tutto nell'ambito dell'esecuzione di una singola chiamata al metodo. `bulkWrite()` Il codice mostra anche come utilizzare [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/BulkWriteOptions.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/BulkWriteOptions.html)e [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/bulk/BulkWriteResult.html)gestire correttamente gli errori dell'`bulkWrite()`operazione. 

```
List < WriteModel < Document >> bulkOperations = new ArrayList < > ();
// get list of 10 documents representing 10 restaurants
List < Document > restaurantsToInsert = getSampleData();

for (Document doc: restaurantsToInsert) {
    bulkOperations.add(new InsertOneModel < > (doc));
}
// Update operation
bulkOperations.add(new UpdateOneModel < > (
    new Document("restaurantId", "REST-Y2E9H5"),
    new Document("", new Document("stats.likes", 20))
    .append("", new Document("rating.average", 4.5))));
// Delete operation
bulkOperations.add(new DeleteOneModel < > (new Document("restaurantId", "REST-D2L431")));

// Perform bulkWrite operation
try {
    BulkWriteOptions options = new BulkWriteOptions()
        .ordered(false); // Allow unordered inserts

    BulkWriteResult result = collection.bulkWrite(bulkOperations, options);

    System.out.println("Inserted: " + result.getInsertedCount());
    System.out.println("Updated: " + result.getModifiedCount());
    System.out.println("Deleted: " + result.getDeletedCount());
} catch (MongoBulkWriteException e) {
    System.err.println("Bulk write error occurred: " + e.getMessage());
    // Log individual write errors
    for (BulkWriteError error: e.getWriteErrors()) {
        System.err.printf("Error at index %d: %s (Code: %d)%n", error.getIndex(), error.getMessage(),
            error.getCode());

        // Log the problematic document
        Document errorDoc = new Document(error.getDetails());
        if (errorDoc != null) {
            System.err.println("Problematic document: " + errorDoc);
        }
    }
} catch (Exception e) {
    System.err.println("Error during bulkWrite: " + e.getMessage());
}
```

**Riprova le scritture**

A differenza di MongoDB, Amazon DocumentDB non supporta scritture riprovabili. Di conseguenza, è necessario implementare una logica di ripetizione personalizzata nelle loro applicazioni, in particolare per la gestione dei problemi di rete o dell'indisponibilità temporanea del servizio. Una strategia di ripetizione dei tentativi ben implementata, in genere, comporta l'aumento del ritardo tra i tentativi e la limitazione del numero totale di tentativi. [Gestione degli errori con la logica di ripetizione](#error-handling)Di seguito è riportato un esempio di codice relativo alla creazione di una logica di ripetizione dei tentativi con la gestione degli errori.

## Lettura e recupero di dati da una raccolta DocumentDB
<a name="reading-retrieving"></a>

L'interrogazione di documenti in Amazon DocumentDB ruota attorno a diversi componenti chiave che consentono di recuperare e manipolare i dati con precisione. Il [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html#find()](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html#find())metodo è l'interrogazione fondamentale APIs nei driver Java MongoDB. Consente il recupero di dati complessi con numerose opzioni per il filtraggio, l'ordinamento e la proiezione dei risultati. Oltre al `find()` metodo, [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Filters.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Filters.html)e [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/FindIterable.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/FindIterable.html)sono altri due componenti fondamentali che forniscono gli elementi costitutivi per le operazioni di interrogazione nei driver Java MongoDB.

La `Filters` classe è una classe di utilità nel driver Java MongoDB che fornisce un'API fluida per la creazione di filtri di query. Questa classe offre metodi di fabbrica statici che creano istanze di `Bson` oggetti che rappresentano varie condizioni di query. I metodi più comunemente usati includono `eq()` per i confronti di uguaglianza,, `gt()` `lt()``gte()`, e `lte()` per i confronti numerici e per la combinazione di più condizioni, `and()` `or()` per i test di appartenenza agli array `in()` e `nin()` per la corrispondenza dei modelli. `regex()` La classe è progettata per essere sicura dai tipi e offre un migliore controllo in fase di compilazione rispetto alle query non elaborate basate su documenti, rendendola l'approccio preferito per la creazione di query DocumentDB nelle applicazioni Java. La gestione degli errori è solida, con chiare eccezioni per le costruzioni di filtri non valide.

`FindIterable`è un'interfaccia specializzata progettata per gestire il risultato del metodo. `find()` Fornisce un ricco set di metodi per perfezionare e controllare l'esecuzione delle query, offrendo un'API fluida per il concatenamento dei metodi. L'interfaccia include metodi essenziali di modifica delle query, come `limit()` la limitazione del numero di documenti restituiti, l'impaginazione, `skip()` l'ordinamento dei risultati, `sort()` la selezione di campi specifici e `projection()` la selezione dell'indice. `hint()` Le operazioni batch, skip e limit di `FindIterable` sono strumenti essenziali di impaginazione e gestione dei dati che aiutano a controllare il modo in cui i documenti vengono recuperati ed elaborati dal database.

Batching (`batchSize`) controlla quanti documenti DocumentDB restituisce al client in un singolo round trip di rete. Quando si imposta una dimensione del batch, DocumentDB non restituisce tutti i documenti corrispondenti contemporaneamente, ma li restituisce invece in gruppi della dimensione del batch specificata. 

Skip consente di compensare il punto di partenza dei risultati, essenzialmente dicendo a DocumentDB di ignorare un determinato numero di documenti prima di iniziare a restituire le corrispondenze. Ad esempio, `skip(20)` ignorerà i primi 20 documenti corrispondenti. Questo è comunemente usato negli scenari di impaginazione in cui si desidera recuperare pagine successive di risultati. 

Il limite limita il numero totale di documenti che possono essere restituiti da una query. Quando si specifica`limit(n)`, DocumentDB smetterà di restituire documenti dopo aver restituito 'n' documenti, anche se ci sono più corrispondenze nel database. 

`FindIterable`supporta modelli di iteratori e cursori durante il recupero di documenti da Amazon DocumentDB. Il vantaggio dell'utilizzo `FindIterable` di un iteratore è che consente il caricamento lento dei documenti e recupera i documenti solo quando richiesto dall'applicazione. Un altro vantaggio dell'utilizzo di iterator è che non sei responsabile del mantenimento della connessione al cluster e quindi non è richiesta la chiusura esplicita della connessione. 

`FindIterable`forniscono inoltre il supporto per [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCursor.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCursor.html)cui è possibile utilizzare i modelli di cursore quando si lavora con le query di Amazon DocumentDB. `MongoCursor`è un'implementazione specifica del driver Java MongoDB che fornisce il controllo sulle operazioni del database e sulla gestione delle risorse. Implementa l'`AutoCloseable`interfaccia, consentendo la gestione esplicita delle risorse tramite try-with-resources blocchi, fondamentale per chiudere correttamente le connessioni al database e liberare le risorse del server. Per impostazione predefinita, il timeout del cursore è di 10 minuti e DocumentDB non offre la possibilità di modificare questo comportamento di timeout. Quando lavorate con dati in batch, assicuratevi di recuperare il gruppo di dati successivo prima del timeout del cursore. Una considerazione fondamentale durante l'utilizzo `MongoCursor` è che richiede una chiusura esplicita per evitare perdite di risorse.

In questa sezione, vengono presentati diversi esempi di`find()`, `Filters` e. `FindIterable`

Il seguente esempio di codice mostra come `find()` recuperare un singolo documento utilizzando il relativo campo «RestaurantID»:

```
Document filter = new Document("restaurantId", "REST-21G145");
Document result = collection.find(filter).first();
```

Anche se l'utilizzo `Filters` consente un migliore controllo degli errori in fase di compilazione, il driver java consente anche di specificare un `Bson` filtro direttamente nel metodo. `find()` Il seguente codice di esempio passa il `Bson` documento a`find()`:

```
result = collection.find(new Document("$and", Arrays.asList(
    new Document("rating.totalReviews", new Document("$gt", 1000)),
    new Document("priceRange", "$$"))))
```

Il codice di esempio successivo mostra diversi esempi di utilizzo della `Filters` classe con`find()`:

```
FindIterable < Document > results;

// Exact match
results = collection.find(Filters.eq("name", "Thai Curry Palace"));

// Not equal
results = collection.find(Filters.ne("cuisine", "Thai"));

// find an element in an array
results = collection.find(Filters.in("features", Arrays.asList("Private Dining")));

// Greater than
results = collection.find(Filters.gt("rating.average", 3.5));

// Between (inclusive)
results = collection.find(Filters.and(
    Filters.gte("rating.totalReviews", 100),
    Filters.lte("rating.totalReviews", 200)));
// AND
results = collection.find(Filters.and(
    Filters.eq("cuisine", "Thai"),
    Filters.gt("rating.average", 4.5)));

// OR
results = collection.find(Filters.or(
    Filters.eq("cuisine", "Thai"),
    Filters.eq("cuisine", "American")));


// All document where the Field exists
results = collection.find(Filters.exists("michelin"));

// Regex
results = collection.find(Filters.regex("name", Pattern.compile("Curry", Pattern.CASE_INSENSITIVE)));

// Find all document where the array contain the list of value regardless of its order
results = collection.find(Filters.all("features", Arrays.asList("Private Dining", "Parking")));

// Array size
results = collection.find(Filters.size("features", 4));
```

L'esempio seguente mostra come concatenare le operazioni di `sort()``skip()`,`limit()`, e `batchSize()` su un `FindIterable` oggetto. L'ordine in cui vengono fornite queste operazioni influirà sulle prestazioni della query. Come procedura ottimale, l'ordine di queste operazioni dovrebbe essere `sort()``projection()`,`skip()`, `limit()` e`batchSize()`.

```
FindIterable < Document > results = collection.find(Filters.gt("rating.totalReviews", 1000))
    // Sorting
    .sort(Sorts.orderBy(
        Sorts.descending("address.city"),
        Sorts.ascending("cuisine")))
    // Field selection
    .projection(Projections.fields(
        Projections.include("name", "cuisine", "priceRange"),
        Projections.excludeId()))

    // Pagination
    .skip(20)
    .limit(10)
    .batchSize(2);
```

Il codice di esempio seguente mostra la creazione di un iteratore su`FindIterable`. Utilizza il `forEach` costrutto di Java per esplorare il set di risultati.

```
collection.find(Filters.eq("cuisine", "American")).forEach(doc -> System.out.println(doc.toJson()));
```

Nell'ultimo esempio di `find()` codice, mostra come utilizzarlo `cursor()` per il recupero dei documenti. Crea il cursore nel blocco try che assicura che il cursore si chiuda quando il codice esce dal blocco try.

```
try (MongoCursor < Document > cursor = collection.find(Filters.eq("cuisine", "American"))
    .batchSize(25)
    .cursor()) {
    while (cursor.hasNext()) {
        Document doc = cursor.next();
        System.out.println(doc.toJson());
    }
} // Cursor automatically closed
```

## Aggiornamento di documenti esistenti in una raccolta DocumentDB
<a name="updating-documents"></a>

Amazon DocumentDB offre meccanismi flessibili e potenti per modificare i documenti esistenti e inserirne di nuovi quando non esistono. Il driver Java MongoDB offre diversi metodi per gli aggiornamenti`updateOne()`: per l'aggiornamento di singoli documenti`updateMany()`, per l'aggiornamento di più documenti `replaceOne()` e per la sostituzione completa dei documenti. Oltre a questi tre metodi, [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Updates.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Updates.html), e [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/UpdateResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/UpdateResult.html)ci sono altri componenti fondamentali che forniscono gli elementi costitutivi per le operazioni di aggiornamento nei driver Java MongoDB. 

La `Updates` classe del driver Java MongoDB è una classe di utilità che fornisce metodi di fabbrica statici per la creazione di operatori di aggiornamento. Funge da generatore principale per la creazione di operazioni di aggiornamento in modo leggibile e sicuro dai tipi. Metodi di base come `set()` e `inc()` consentono `unset()` la modifica diretta dei documenti. La potenza di questa classe diventa evidente quando si combinano più operazioni utilizzando il `Updates.combine()` metodo che consente di eseguire più operazioni di aggiornamento atomicamente, garantendo la coerenza dei dati.

`UpdateOptions`è una potente classe di configurazione nel driver Java di MongoDB che fornisce funzionalità di personalizzazione essenziali per le operazioni di aggiornamento dei documenti. Due aspetti importanti di questa classe sono il supporto dei filtri upsert e array per le operazioni di aggiornamento. La funzione upsert, abilitata tramite`upsert(true)`, consente la creazione di nuovi documenti quando non vengono trovati documenti corrispondenti durante un'operazione di aggiornamento. Tramite`arrayFilters()`, l'operazione di aggiornamento può aggiornare con precisione gli elementi dell'array che soddisfano criteri specifici.

`UpdateResult`nel driver Java di MongoDB fornisce il meccanismo di feedback che descrive in dettaglio l'esito di un'operazione di aggiornamento. Questa classe incapsula tre metriche chiave: il numero di documenti corrispondenti ai criteri di aggiornamento (`matchedCount`), il numero di documenti effettivamente modificati () e le informazioni su eventuali documenti alterati (`modifiedCount`). `upsertedId` La comprensione di queste metriche è essenziale per la corretta gestione degli errori, la verifica delle operazioni di aggiornamento e il mantenimento della coerenza dei dati nelle applicazioni.

### Aggiorna e sostituisci un singolo documento
<a name="update-single-doc"></a>

In DocumentDB, l'aggiornamento di un singolo documento può essere eseguito utilizzando il metodo updateOne (). Questo metodo utilizza un parametro di filtro, solitamente fornito dalla `Filters` classe, per identificare il documento da aggiornare, un parametro `Updat` e che determina quali campi aggiornare e un `UpdateOptions` parametro opzionale per impostare diverse opzioni per l'aggiornamento. L'utilizzo del `updateOne()` metodo aggiornerà solo il primo documento che corrisponde ai criteri di selezione. Il codice di esempio seguente aggiorna un singolo campo di un documento:

```
collection.updateOne(Filters.eq("restaurantId", "REST-Y2E9H5"),
    Updates.set("name", "Amazing Japanese sushi"));
```

Per aggiornare più campi in un documento, utilizzate `updateOne()` with `Update.combine()` come illustrato nell'esempio seguente. Questo esempio mostra anche come aggiungere un elemento a una matrice nel documento.

```
List<Bson> updates = new ArrayList<>();
// Basic field updates
updates.add(Updates.set("name", "Shanghai Best"));
// Array operations
updates.add(Updates.addEachToSet("features", Arrays.asList("Live Music")));
// Counter updates
updates.add(Updates.inc("rating.totalReviews", 10));
// Combine all updates
Bson combinedUpdates = Updates.combine(updates);
// Execute automic update with one call
collection.updateOne(Filters.eq("restaurantId","REST-1J83NH"), combinedUpdates);
```

Il seguente esempio di codice mostra come aggiornare un documento nel database. Se il documento specificato non esiste, l'operazione lo inserirà automaticamente come nuovo documento. Questo codice mostra anche come utilizzare le metriche disponibili tramite l'`UpdateResult`oggetto.

```
Bson filter = Filters.eq("restaurantId", "REST-0Y9GL0");
Bson update = Updates.set("cuisine", "Indian");
// Upsert operation
UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult result = collection.updateOne(filter, update, options);

if (result.getUpsertedId() != null) {
   	System.out.println("Inserted document with _id: " + result.getUpsertedId());
} else {
    	System.out.println("Updated " + result.getModifiedCount() + " document(s)");
}
```

Il seguente esempio di codice dimostra come sostituire completamente un documento esistente con un nuovo documento utilizzando il `replaceOne()` metodo, anziché aggiornare i singoli campi. Il `replaceOne()` metodo sovrascrive l'intero documento, preservando solo il `_id` campo dell'originale. Se più documenti soddisfano i criteri di filtro, viene sostituito solo il primo documento rilevato.

```
Document newDocument = new Document()
                .append("restaurantId", "REST-0Y9GL0")
                .append("name", "Bhiryani Adda")
                .append("cuisine", "Indian")
                .append("rating", new Document()
                        .append("average", 4.8)
                        .append("totalReviews", 267))
                .append("features", Arrays.asList("Outdoor Seating", "Live Music"));

UpdateResult result = collection.replaceOne(
                    Filters.eq("restaurantId", "REST-0Y9GL0"),
                    newDocument);
System.out.printf("Modified %d document%n", result.getModifiedCount());
```

### Aggiorna più documenti
<a name="update-multiple-docs"></a>

Esistono due modi per aggiornare più documenti in una raccolta contemporaneamente. È possibile utilizzare il `updateMany()` metodo o utilizzare il [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/UpdateManyModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/UpdateManyModel.html)con il `bulkWrite()` metodo. Il `updateMany()` metodo utilizza un parametro di filtro per selezionare i documenti da aggiornare, il `Update` parametro per identificare i campi da aggiornare e un `UpdateOptions` parametro opzionale per specificare le opzioni di aggiornamento.

Il codice di esempio seguente illustra l'utilizzo del `updateMany()` metodo:

```
Bson filter = Filters.and(
    Filters.in("features", Arrays.asList("Private Dining")),
    Filters.eq("cuisine", "Thai"));
UpdateResult result1 = collection.updateMany(filter, Updates.set("priceRange", "$$$"));
```

Il codice di esempio seguente mostra il `bulkWrite()` metodo utilizzando lo stesso aggiornamento:

```
BulkWriteOptions options = new BulkWriteOptions().ordered(false);
List < WriteModel < Document >> updates = new ArrayList < > ();
Bson filter = Filters.and(
    Filters.in("features", Arrays.asList("Private Dining")),
    Filters.eq("cuisine", "Indian"));
Bson updateField = Updates.set("priceRange", "$$$");
updates.add(new UpdateManyModel < > (filter, updateField));
BulkWriteResult result = collection.bulkWrite(updates, options);
System.out.printf("Modified %d document%n", result.getModifiedCount());
```

## Rimuovere documenti da una raccolta DocumentDB
<a name="deleting-documents"></a>

Il driver Java MongoDB `deleteOne()` consente di rimuovere un singolo documento `deleteMany()` e di rimuovere più documenti che soddisfano criteri specifici. Proprio come l'aggiornamento, anche l'operazione di eliminazione può essere utilizzata con il `bulkWrite()` metodo. Entrambi `deleteOne()` `deleteMany()` restituiscono un [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/DeleteResult.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/result/DeleteResult.html)oggetto che fornisce informazioni sull'esito dell'operazione, incluso il numero di documenti eliminati. Di seguito è riportato un esempio di utilizzo `deleteMany()` per rimuovere più documenti:

```
Bson filter = Filters.and(
    Filters.eq("cuisine", "Thai"),
    Filters.lt("rating.totalReviews", 50));
DeleteResult result = collection.deleteMany(filter);
System.out.printf("Deleted %d document%n", result.getDeletedCount());
```

## Gestione degli errori con la logica di ripetizione
<a name="error-handling"></a>

Una solida strategia di gestione degli errori per Amazon DocumentDB dovrebbe implementare la classificazione degli errori in riprovabili (come timeout di rete, problemi di connessione) e non riprovabili (come errori di autenticazione, query non valide). In caso di errori operativi dovuti a errori che devono essere ritentati, dovrebbe prevedere un intervallo di tempo tra ogni tentativo e il numero massimo di tentativi. Le operazioni CRUD dovrebbero trovarsi in un blocco try-catch che cattura [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoException.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoException.html)e le sue sottoclassi. Inoltre, dovrebbe includere il monitoraggio e la registrazione degli errori per la visibilità operativa. Di seguito è riportato un codice di esempio che mostra come implementare la gestione degli errori tra tentativi:

```
int MAX_RETRIES = 3;
int INITIAL_DELAY_MS = 1000;
int retryCount = 0;

while (true) {
    try {
        crud_operation(); //perform crud that will throw MongoException or one of its subclass
        break;
    } catch (MongoException e) {
        if (retryCount < MAX_RETRIES) {
            retryCount++;
            long delayMs = INITIAL_DELAY_MS * (long) Math.pow(2, retryCount - 1);
            try {
                TimeUnit.MILLISECONDS.sleep(delayMs);
            } catch (InterruptedException t) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Retry interrupted", t);
            }
            continue;
        } else
            throw new RuntimeException("Crud operation failed", e);
    }
}
```