

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.

# Amazon DocumentDB Java-Programmierhandbuch
<a name="docdb-java-pg"></a>

Dieses umfassende Handbuch bietet eine detaillierte Anleitung zur Arbeit mit Amazon DocumentDB unter Verwendung der Java-Treiber von MongoDB und behandelt wichtige Aspekte des Datenbankbetriebs und der Datenbankverwaltung.

**Topics**
+ [Einführung](#java-pg-intro)
+ [Voraussetzungen](#java-pg-prereqs)
+ [Datenmodelle](#java-pg-data-models)
+ [Verbindung mit einem Java-Treiber herstellen](java-pg-connect-mongo-driver.md)
+ [CRUD-Operationen mit Java](java-crud-operations.md)
+ [Indexverwaltung mit Java](index-management-java.md)
+ [Ereignisgesteuerte Programmierung](event-driven-programming.md)

## Einführung
<a name="java-pg-intro"></a>

Das Handbuch beginnt mit der Konnektivität und erklärt, wie sichere Verbindungen zu DocumentDB-Clustern mithilfe des MongoDB-Java-Treibers hergestellt werden. Es beschreibt die Komponenten der Verbindungszeichenfolge, die SSL/TLS Implementierung und die verschiedenen Verbindungsoptionen, einschließlich IAM-Authentifizierung und Verbindungspooling, sowie robuste Strategien zur Fehlerbehandlung.

Im Abschnitt CRUD-Operationen (Create, Read, Update, Delete) behandelt das Handbuch ausführlich die Bearbeitung von Dokumenten und zeigt, wie Dokumente sowohl mit Einzel- als auch mit Massenoperationen erstellt, gelesen, aktualisiert und gelöscht werden. Es erklärt die Verwendung von Filtern, Abfragen und verschiedenen Operationsoptionen und betont gleichzeitig bewährte Methoden für die Fehlerbehandlung und die Implementierung von Wiederholungslogik zur Erhöhung der Zuverlässigkeit. Der Leitfaden befasst sich auch ausführlich mit der Indexverwaltung und beschreibt detailliert die Erstellung und Verwaltung verschiedener Indextypen, darunter Einzelfeld-, zusammengesetzte Indizes, Sparse-Indizes und Textindizes. Es wird erklärt, wie die Abfrageleistung durch die richtige Indexauswahl und die Verwendung der `explain()` Funktion zur Analyse von Abfrageausführungsplänen optimiert werden kann.

Der letzte Abschnitt konzentriert sich auf ereignisgesteuertes Programmieren mithilfe der Change-Streams von Amazon DocumentDB und zeigt, wie die Überwachung von Datenänderungen in Echtzeit in Java-Anwendungen implementiert werden kann. Er behandelt die Implementierung von Change-Stream-Cursors, den Umgang mit Resume-Token für den kontinuierlichen Betrieb und zeitbasierte Operationen für die Verarbeitung historischer Daten. Der gesamte Leitfaden enthält praktische Codebeispiele und bewährte Methoden, was ihn zu einer unschätzbaren Ressource für Sie macht, wenn Sie robuste Java-Anwendungen mit Amazon DocumentDB erstellen möchten.

## Voraussetzungen
<a name="java-pg-prereqs"></a>

Stellen Sie vor dem Beginn sicher, dass Sie über das Folgende verfügen:
+ Ein AWS Konto mit einem konfigurierten DocumentDB-Cluster. Informationen zur Einrichtung eines DocumentDB-Clusters finden Sie in diesem [Blogbeitrag „Erste Schritte](https://aws.amazon.com/blogs/database/part-1-getting-started-with-amazon-documentdb-using-amazon-ec2/)“.
+ Java Development Kit (JDK) installiert (wir werden [Amazon Corretto 21](https://docs.aws.amazon.com/corretto/latest/corretto-21-ug/downloads-list.html) für dieses Handbuch verwenden).
+ Maven für das Abhängigkeitsmanagement.

## Datenmodelle für diesen Leitfaden
<a name="java-pg-data-models"></a>

Der gesamte Beispielcode in diesem Handbuch geht von einer Verbindung zu einer Testdatenbank „ProgGuideData“ aus, die eine Sammlung „Restaurants“ enthält. Alle Beispielcodes in diesem Handbuch funktionieren auf einem Restauranteintragssystem. Im Folgenden finden Sie ein Beispiel dafür, wie ein Dokument in diesem System aussieht:

```
{
    "_id": "ab6ad8f119b5bca3efa2c7ae",
    "restaurantId": "REST-CRT9BL",
    "name": "Thai Curry Palace",
    "description": "Amazing Restaurant, must visit",
    "cuisine": "Thai",
    "address": {
        "street": "914 Park Street",
        "city": "Bryan",
        "state": "AL",
        "zipCode": "96865",
        "location": {
            "type": "Point",
            "coordinates": [-25.4619, 8.389]
        }
    },
    "contact": {
        "phone": "(669) 915-9056 x6657"
    },
    "rating": {
        "average": 3.4,
        "totalReviews": 275
    },
    "priceRange": "$",
    "menu": [{
        "category": "Appetizers",
        "items": [{
            "name": "Buffalo Chicken Wings",
            "price": 13.42
        }]
    }],
    "features": [
        "Private Dining"
    ],
    "isActive": false“ michelin”: {“
        star”: 3,
        “ranking_years”: 4
    }
}
```

Alle Codebeispiele, die CRUD, Indexverwaltung und ereignisgesteuerte Programmierung zeigen, gehen davon aus, dass Sie über ein [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html)Objekt`dbClient`, ein Objekt und ein [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoDatabase.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoDatabase.html)Objekt `connectionDB` verfügen. [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())`collection`

**Anmerkung**  
Alle Codebeispiele in diesem Handbuch wurden mit der MongoDB-Java-Treiberversion 5.3.0 getestet.

# Mit einem MongoDB-Java-Treiber eine Verbindung zu Amazon DocumentDB herstellen
<a name="java-pg-connect-mongo-driver"></a>

Dieser Abschnitt enthält eine step-by-step Anleitung für die Verbindung mit Amazon DocumentDB mithilfe von Java-Treibern. Auf diese Weise können Sie mit der Integration von DocumentDB in Ihre Java-Anwendungen beginnen.

**Topics**
+ [Schritt 1: Einrichten des Projekts](#step1-set-up)
+ [Schritt 2: Erstellen Sie die Verbindungszeichenfolge](#step2-create-connection-string)
+ [Schritt 3: Schreiben Sie den Verbindungscode](#step3-write-connect-code)
+ [Schritt 4: Verbindungsausnahmen behandeln](#step4-handle-connect-exceptions)
+ [Schritt 5: Den Code ausführen](#step5-running-code)
+ [Bewährte Methoden für Verbindungen](#java-connect-best-practices)

## Schritt 1: Einrichten des Projekts
<a name="step1-set-up"></a>

1. Erstellen Sie mit Maven ein Java-Projekt:

   ```
   mvn archetype:generate -DgroupId=com.docdb.guide -DartifactId=my-docdb-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
   ```

1. Fügen Sie den MongoDB-Java-Treiber als Abhängigkeit für das Projekt in Ihrer Datei 'pom.xml' hinzu:

   ```
   <dependency>
       <groupId>org.mongodb</groupId>
       <artifactId>mongodb-driver-sync</artifactId> 
       <version>5.3.0</version> 
   </dependency>
   ```

## Schritt 2: Erstellen Sie die Verbindungszeichenfolge
<a name="step2-create-connection-string"></a>

Die Amazon DocumentDB DocumentDB-Verbindungszeichenfolge ist wichtig, um eine Verbindung zwischen Ihrer Anwendung und Ihrem DocumentDB-Cluster herzustellen. Diese Zeichenfolge enthält wichtige Informationen wie den Cluster-Endpunkt, den Port, Authentifizierungsdetails und verschiedene Verbindungsoptionen. Um eine DocumentDB-Verbindungszeichenfolge zu erstellen, beginnen Sie normalerweise mit dem Basisformat:

```
"mongodb://username:password@cluster-endpoint:port/?[connection options]"
```

Sie müssen „Benutzername“ und „Passwort“ durch Ihre tatsächlichen Anmeldeinformationen ersetzen. Den Endpunkt und die Portnummer Ihres Clusters finden Sie sowohl im AWS-Managementkonsole als auch über AWS CLI. Informationen [Die Endpunkte eines Clusters finden](db-cluster-endpoints-find.md) zum Finden des Cluster-Endpunkts für Ihren Cluster finden Sie unter. Der Standardport für DocumentDB ist 27017.

**Beispiele für Verbindungszeichenfolgen**
+ Herstellen einer Verbindung zu DocumentDB mithilfe von Verschlüsselung bei der Übertragung und Sicherstellung, dass Leseanforderungen an Read Replicas und Schreiben an Primary weitergeleitet werden:

  ```
  "mongodb://username:password@cluster-endpoint:27017/?tls=true& 
     tlsCAFile=global-bundle.pem& 
     readPreference=secondaryPreferred&
     retryWrites=false"
  ```
+ Herstellen einer Verbindung zu DocumentDB mithilfe der IAM-Authentifizierung:

  ```
  "mongodb://cluster-endpoint:27017/?tls=true& 
     tlsCAFile=global-bundle.pem& 
     readPreference=secondaryPreferred&
     retryWrites=false&
     authSource=%24external&
     authMechanism=MONGODB-AWS"
  ```

Die verschiedenen Optionen, die für die Verbindungszeichenfolge verfügbar sind, lauten wie folgt:
+ [TLS-Zertifikat](#connection-string-tls)
+ [Aus gelesenen Replikaten lesen](#connection-string-read-rep)
+ [Schreiben Sie ein Anliegen und führen Sie ein Tagebuch](#connection-string-write-journal)
+ [RetryWrites](#connection-string-retry-writes)
+ [IAM-Authentifizierung](#connection-string-iam-auth)
+ [Verbindungspool](#connection-string-pool)
+ [Parameter für das Verbindungs-Timeout](#connection-string-timeout)

### TLS-Zertifikat
<a name="connection-string-tls"></a>

**`tls=true|false`**— Diese Option aktiviert oder deaktiviert Transport Layer Security (TLS). Standardmäßig ist die Verschlüsselung bei der Übertragung auf dem Amazon DocumentDB-Cluster aktiviert. Daher sollte der Wert für diese Option lauten, sofern TLS nicht auf Cluster-Ebene deaktiviert ist. `true`

Bei Verwendung von TLS muss der Code ein SSL-Zertifikat bereitstellen, wenn eine Verbindung zu einem DocumentDB-Cluster hergestellt wird. Laden Sie das Zertifikat herunter, das für die sichere Verbindung zum Cluster erforderlich ist: [https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem](https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem). Es gibt zwei Möglichkeiten, die `global-bundle.pem` Datei zu verwenden.
+ **Option 1** — Extrahieren Sie alle Zertifikate aus der `global-bundle.pem` Datei und speichern Sie sie mit dem Keytool von Java in einer `.jks` Datei, die später im Code verwendet werden kann. Das Skript, das zeigt, wie [Verbindung bei aktiviertem TLS herstellen](connect_programmatically.md#connect_programmatically-tls_enabled) das geht, finden Sie auf der Registerkarte Java.
+ **Option 2** — Fügen Sie die `global-bundle.pem` Datei dynamisch zum Code hinzu, erstellen Sie einen Keystore im Arbeitsspeicher und verwenden Sie ihn`SSLContext`, um das Zertifikat beim Herstellen der Verbindung bereitzustellen.

### Aus gelesenen Replikaten lesen
<a name="connection-string-read-rep"></a>

**`replicaSet=rs0&readPreference=secondaryPreferred`**— Wenn Sie diese beiden Optionen angeben, werden alle Leseanforderungen an die Read Replicas und Schreibanforderungen an die primäre Instanz weitergeleitet. Durch die Verwendung `replicaSet=rs0` in der Verbindungszeichenfolge kann der MongoDB-Treiber eine automatisch aktualisierte Ansicht der Cluster-Topologie beibehalten, sodass Anwendungen die Sichtbarkeit der aktuellen Knotenkonfigurationen beibehalten können, wenn Instanzen hinzugefügt oder entfernt werden. Wenn Sie diese Optionen nicht angeben oder angeben, werden alle Lese- und Schreibvorgänge an die primäre Instanz `readPreference=primary` gesendet. Weitere Optionen für finden `readPreference` Sie unter[Lesen Sie die Einstellungsoptionen](how-it-works.md#durability-consistency-isolation).

### Schreiben Sie ein Anliegen und führen Sie ein Tagebuch
<a name="connection-string-write-journal"></a>

Das Problem mit Schreibvorgängen bestimmt den Grad der Bestätigung, die von der Datenbank für Schreibvorgänge angefordert wird. MongoDB-Treiber bieten eine Option zur Optimierung von Schreib-, Bedenken- und Journaldateien. Amazon DocumentDB erwartet nicht, dass Sie Write Concern und Journal festlegen, und ignoriert die Werte, die für `w` und `j` (`writeConcern`und`journal`) gesendet werden. DocumentDB schreibt Daten immer mit`writeConcern`: `majority` und`journal`:, `true` sodass die Schreibvorgänge auf den meisten Knoten dauerhaft aufgezeichnet werden, bevor eine Bestätigung an den Client gesendet wird.

### RetryWrites
<a name="connection-string-retry-writes"></a>

**`retryWrites=false`**— DocumentDB unterstützt keine wiederholbaren Schreibvorgänge und daher sollte dieses Attribut immer auf gesetzt werden. `false`

### IAM-Authentifizierung
<a name="connection-string-iam-auth"></a>

**`authSource=%24external`und `authMechanism=MONGODB-AWS`** — Diese beiden Parameter werden zur Authentifizierung mit verwendet. AWS Identity and Access Management Die IAM-Authentifizierung ist derzeit nur in der instanzbasierten Cluster-Version 5.0 verfügbar. Weitere Informationen finden Sie unter [Authentifizierung mit IAM-Identität](iam-identity-auth.md).

### Verbindungspool
<a name="connection-string-pool"></a>

Diese Optionen sind für das Verbindungspooling verfügbar:
+ **`maxPoolSize`**— Legt die maximale Anzahl von Verbindungen fest, die im Pool erstellt werden können. Wenn alle Verbindungen verwendet werden und eine neue Anfrage eingeht, wartet es darauf, dass eine Verbindung verfügbar wird. Die Standardeinstellung für MongoDB-Java-Treiber ist 100.
+ **`minPoolSize`**— Gibt die Mindestanzahl von Verbindungen an, die jederzeit im Pool aufrechterhalten werden sollten. Die Standardeinstellung für MongoDB-Java-Treiber ist 0.
+ **`maxIdleTimeMS`**— Legt fest, wie lange eine Verbindung im Pool inaktiv bleiben kann, bevor sie geschlossen und entfernt wird. Die Standardeinstellung für MongoDB-Java-Treiber ist 100 Millisekunden.
+ **`waitQueueTimeoutMS`**— Konfiguriert, wie lange ein Thread warten soll, bis eine Verbindung verfügbar wird, wenn der Pool seine maximale Größe erreicht hat. Wenn innerhalb dieser Zeit keine Verbindung verfügbar ist, wird eine Ausnahme ausgelöst. Der Standardwert für MongoDB-Java-Treiber ist 120.000 Millisekunden (2 Minuten).

### Parameter für das Verbindungs-Timeout
<a name="connection-string-timeout"></a>

Timeout ist ein Mechanismus zur Begrenzung der Zeit, die ein Vorgang oder ein Verbindungsversuch dauern kann, bis er als fehlgeschlagen betrachtet wird. Die folgenden Timeout-Parameter sind verfügbar, um unbefristete Wartezeiten zu verhindern und die Ressourcenzuweisung zu verwalten:
+ **`connectTimeoutMS`**— Konfiguriert, wie lange der Treiber wartet, um eine Verbindung zum Cluster herzustellen. Die Standardeinstellung ist 10.000 Millisekunden (10 Sekunden).
+ **`socketTimeoutMS`**— Gibt an, wie lange der Treiber bei einem Nicht-Schreibvorgang auf eine Antwort vom Server wartet. Die Standardeinstellung ist 0 (kein Timeout oder unendlich).
+ **`serverSelectionTimeoutMS`**— Gibt an, wie lange der Treiber warten wird, um einen verfügbaren Server im Cluster zu finden. Der Standardwert für diese Einstellung ist 30 Sekunden und reicht aus, damit beim Failover eine neue primäre Instanz ausgewählt werden kann.

## Schritt 3: Schreiben Sie den Verbindungscode
<a name="step3-write-connect-code"></a>

Das folgende Codebeispiel zeigt, wie eine TLS-Verbindung zu Amazon DocumentDB hergestellt wird:
+ Es erstellt die Objekte Java [https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.html](https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.html)und [`SSLContext`>](https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLContext.html).
+ Es erstellt das [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoClientSettings.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoClientSettings.html)Objekt auch, indem es es an das [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html)Objekt übergibt. Um eine TLS-Verbindung herzustellen, müssen Sie das `MongoClientSettings` Objekt verwenden, um das `connectionstring` und zu binden`sslcontext`.
+ Using [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClients.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClients.html)ruft ein [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html)Objekt ab.

```
public static MongoClient makeDbConnection(String dbName, String DbUserName, String DbPassword,
    String DbClusterEndPoint, String keyStorePass) throws Exception {
    MongoClient connectedClient;
    String connectionOptions = "?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false";
    String connectionUrl = "mongodb://" + DbUserName + ":" + DbPassword + "@" + DbClusterEndPoint + ":27017/" +
        dbName + connectionOptions;

    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        try (FileInputStream fis = new FileInputStream("src/main/resources/certs/truststore.jks")) {
            trustStore.load(fis, keyStorePass.toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(trustStore);

            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
            ConnectionString connectionString = new ConnectionString(connectionUrl);
            MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .applyToSslSettings(builder - > {
                    builder.enabled(true);
                    builder.context(sslContext);
                })
                .build();
            connectedClient = MongoClients.create(settings);
        }
        return connectedClient;
    } catch (MongoException e5) {
        throw new RuntimeException(e5);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
```

## Schritt 4: Verbindungsausnahmen behandeln
<a name="step4-handle-connect-exceptions"></a>

Bei der Arbeit mit DocumentDB in Java-Anwendungen ist die Behandlung von Verbindungsausnahmen entscheidend für die Aufrechterhaltung robuster und zuverlässiger Datenbankoperationen. Durch die richtige Verwaltung helfen diese Ausnahmen nicht nur bei der schnellen Diagnose von Problemen, sondern stellen auch sicher, dass Ihre Anwendung mit vorübergehenden Netzwerkunterbrechungen oder Serverausfällen problemlos umgehen kann, was zu einer verbesserten Stabilität und Benutzererfahrung führt. Zu den wichtigsten Ausnahmen im Zusammenhang mit dem Verbindungsaufbau gehören:
+ **`MongoException`**— Eine allgemeine Ausnahme, die für verschiedene Szenarien gelten könnte, die nicht durch speziellere Ausnahmen abgedeckt sind. Stellen Sie sicher, dass diese Ausnahme nach allen anderen spezifischen Ausnahmen behandelt wird, da es sich um eine catch MongoDB-Ausnahme handelt.
+ **`MongoTimeoutException`**— Wird ausgegeben, wenn bei einem Vorgang das Zeitlimit überschritten wird. Zum Beispiel die Abfrage eines nicht vorhandenen Cluster-Endpunkts.
+ **`MongoSocketException`**— Ausgestellt für Netzwerkprobleme. Zum Beispiel eine plötzliche Netzwerkunterbrechung während eines Vorgangs. 
+ **`MongoSecurityException`**— Wird ausgegeben, wenn die Authentifizierung fehlschlägt. Zum Beispiel, wenn eine Verbindung mit falschen Anmeldeinformationen hergestellt wird. 
+ **`MongoConfigurationException`**— Wird ausgegeben, wenn in der Client-Konfiguration ein Fehler auftritt. Zum Beispiel, wenn eine ungültige Verbindungszeichenfolge verwendet wird.

## Schritt 5: Den Code ausführen
<a name="step5-running-code"></a>

Das folgende Codebeispiel erstellt eine Amazon DocumentDB DocumentDB-Verbindung und druckt alle Datenbanken:

```
public static void TestConnection() {
    try (MongoClient mongoClient = makeDbConnection(DATABASE_NAME, DB_USER_NAME, DB_PASSWORD, DB_CLUSTER_ENDPOINT, KEYSTORE_PASSWORD)) {
        List < String > databases = mongoClient.listDatabaseNames().into(new ArrayList < > ());
        System.out.println("Databases: " + databases);
    } catch (MongoException e) {
        System.err.println("MongoDB error: " + e.getMessage());
        throw new RuntimeException(e);
    }
}
```

## Bewährte Methoden für Verbindungen
<a name="java-connect-best-practices"></a>

Die folgenden bewährten Methoden sollten Sie berücksichtigen, wenn Sie mit einem MongoDB-Java-Treiber eine Verbindung zu Amazon DocumentDB herstellen:
+ Schließen Sie Ihren immer [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html)dann, wenn Sie den Client nicht mehr benötigen, um Ressourcen freizugeben.
+ Behandeln Sie Ausnahmen angemessen und implementieren Sie eine korrekte Fehlerprotokollierung.
+ Verwenden Sie Umgebungsvariablen oder speichern AWS Secrets Manager Sie vertrauliche Informationen wie Benutzernamen und Passwörter.

# Durchführen von CRUD-Vorgängen in Amazon DocumentDB mit Java
<a name="java-crud-operations"></a>

In diesem Abschnitt wird die Durchführung von CRUD-Vorgängen (Create, Read, Update, Delete) in Amazon DocumentDB mithilfe von MongoDB-Java-Treibern beschrieben.

**Topics**
+ [Dokumente in einer DocumentDB-Sammlung erstellen und einfügen](#creating-inserting)
+ [Lesen und Abrufen von Daten aus einer DocumentDB-Sammlung](#reading-retrieving)
+ [Aktualisieren vorhandener Dokumente in einer DocumentDB-Sammlung](#updating-documents)
+ [Dokumente aus einer DocumentDB-Sammlung entfernen](#deleting-documents)
+ [Fehlerbehandlung mit Wiederholungslogik](#error-handling)

## Dokumente in einer DocumentDB-Sammlung erstellen und einfügen
<a name="creating-inserting"></a>

Durch das Einfügen von Dokumenten in Amazon DocumentDB können Sie Ihren Sammlungen neue Daten hinzufügen. Je nach Ihren Bedürfnissen und dem Datenvolumen, mit dem Sie arbeiten, gibt es mehrere Möglichkeiten, Einfügungen durchzuführen. Die einfachste Methode zum Einfügen eines einzelnen Dokuments in die Sammlung ist. `insertOne()` Um mehrere Dokumente gleichzeitig einzufügen, können Sie die `insertMany()` Methode verwenden, mit der Sie eine Reihe von Dokumenten in einem einzigen Vorgang hinzufügen können. Eine andere Methode zum Einfügen vieler Dokumente in eine DocumentDB-Sammlung ist. `bulkWrite()` In diesem Handbuch werden all diese Methoden zum Erstellen von Dokumenten in einer DocumentDB-Sammlung beschrieben.

**`insertOne()`**

Lassen Sie uns zunächst untersuchen, wie ein einzelnes Dokument in eine Amazon DocumentDBB-Sammlung eingefügt wird. Das Einfügen eines einzelnen Dokuments erfolgt mithilfe der Methode. `insertOne()` Diese Methode verwendet [BsonDocument](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/bson/org/bson/BsonDocument.html)für das Einfügen einen Wert und gibt ein [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)Objekt zurück, mit dem die Objekt-ID des neu eingefügten Dokuments abgerufen werden kann. Der folgende Beispielcode zeigt das Einfügen eines Restaurantdokuments in die Sammlung:

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

Achten Sie bei der Verwendung darauf`insertOne()`, eine angemessene Fehlerbehandlung einzubeziehen. Im obigen Code hat „`restaurantId`“ beispielsweise einen eindeutigen Index. Wenn Sie diesen Code erneut ausführen, wird Folgendes ausgelöst`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 ()**

Die wichtigsten Methoden zum Einfügen vieler Dokumente in eine Sammlung sind insertMany () und. `bulkWrite()` 

Die `insertMany()` Methode ist die einfachste Methode, mehrere Dokumente in einem einzigen Vorgang einzufügen. Sie akzeptiert eine Liste von Dokumenten und fügt sie in die Sammlung ein. Diese Methode ist ideal, wenn Sie einen Stapel neuer Dokumente einfügen, die unabhängig voneinander sind und keine speziellen Verarbeitungs- oder Mischoperationen erfordern. Der folgende Code zeigt, wie JSON-Dokumente aus einer Datei gelesen und in die Sammlung eingefügt werden. Die `insertMany()` Funktion gibt ein [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`Objekt zurück, mit dem IDs alle eingefügten Dokumente abgerufen werden können.

```
// 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)**

Die `bulkWrite()` Methode ermöglicht es, mehrere Schreiboperationen (Einfügen, Aktualisieren, Löschen) in einem einzigen Stapel durchzuführen. Sie können `bulkWrite()` sie verwenden, wenn Sie verschiedene Arten von Vorgängen in einem einzigen Stapel ausführen müssen, z. B. wenn Sie einige Dokumente einfügen und andere aktualisieren müssen. `bulkWrite()`unterstützt zwei Arten von Batch-Schreibvorgängen, geordnet und ungeordnet:
+ *Geordnete Operationen* — (Standard) Amazon DocumentDB verarbeitet die Schreibvorgänge sequentiell und stoppt beim ersten Fehler, auf den es stößt. Dies ist nützlich, wenn die Reihenfolge der Operationen wichtig ist, z. B. wenn spätere Operationen von früheren Vorgängen abhängen. Geordnete Operationen sind jedoch im Allgemeinen langsamer als ungeordnete Operationen. Bei geordneten Vorgängen müssen Sie den Fall berücksichtigen, dass der Stapel beim ersten Fehler stoppt und einige Operationen möglicherweise unbearbeitet bleiben.
+ *Ungeordnete Operationen* — Ermöglicht Amazon DocumentDB, Einfügungen als einzelne Ausführung in der Datenbank zu verarbeiten. Wenn bei einem Dokument ein Fehler auftritt, wird der Vorgang mit den übrigen Dokumenten fortgesetzt. Dies ist besonders nützlich, wenn Sie große Datenmengen einfügen und einige Fehler tolerieren können, z. B. bei der Datenmigration oder bei Massenimporten, bei denen einige Dokumente aufgrund doppelter Schlüssel fehlschlagen können. Bei ungeordneten Vorgängen müssen Sie teilweise Erfolgsszenarien berücksichtigen, in denen einige Operationen erfolgreich sind, während andere fehlschlagen.

Bei der Arbeit mit der `bulkWrite()` Methode sind einige wichtige Klassen erforderlich. Erstens dient die [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)Klasse als Basisklasse für alle Schreiboperationen und für spezifische Implementierungen wie [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), und [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)behandelt verschiedene Arten von Operationen.

Die [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)Klasse ist notwendig, um das Verhalten von Massenoperationen zu konfigurieren, z. B. die ordered/unordered Ausführung festzulegen oder die Dokumentenvalidierung zu umgehen. Die [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)Klasse bietet detaillierte Informationen zu den Ausführungsergebnissen, einschließlich der Anzahl der eingefügten, aktualisierten und gelöschten Dokumente.

Für die Fehlerbehandlung ist die [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)Klasse von entscheidender Bedeutung, da sie Informationen über alle Fehler während des Massenvorgangs enthält, während die [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)Klasse spezifische Details zu einzelnen Vorgangsfehlern enthält. Der folgende Code zeigt ein Beispiel für das Einfügen einer Liste von Dokumenten sowie das Aktualisieren und Löschen eines einzelnen Dokuments, alles innerhalb der Ausführung eines einzigen `bulkWrite()` Methodenaufrufs. Der Code zeigt auch, wie mit [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)und gearbeitet wird [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), sowie die korrekte Fehlerbehandlung der `bulkWrite()` Operation. 

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

**Wiederholbare Schreibvorgänge**

Im Gegensatz zu MongoDB unterstützt Amazon DocumentDB keine wiederholbaren Schreibvorgänge. Daher müssen Sie in ihren Anwendungen eine benutzerdefinierte Wiederholungslogik implementieren, insbesondere zur Behandlung von Netzwerkproblemen oder vorübergehender Nichtverfügbarkeit von Diensten. Eine gut implementierte Wiederholungsstrategie besteht in der Regel darin, die Verzögerung zwischen Wiederholungsversuchen zu erhöhen und die Gesamtzahl der Wiederholungsversuche zu begrenzen. [Fehlerbehandlung mit Wiederholungslogik](#error-handling)Im Folgenden finden Sie ein Codebeispiel für die Erstellung einer Wiederholungslogik mit Fehlerbehandlung.

## Lesen und Abrufen von Daten aus einer DocumentDB-Sammlung
<a name="reading-retrieving"></a>

Das Abfragen von Dokumenten in Amazon DocumentDB basiert auf mehreren Schlüsselkomponenten, mit denen Sie Daten präzise abrufen und bearbeiten können. Die [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())Methode ist die grundlegende Abfrage APIs in MongoDB-Java-Treibern. Sie ermöglicht den komplexen Datenabruf mit zahlreichen Optionen zum Filtern, Sortieren und Projizieren von Ergebnissen. Neben der `find()` Methode [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)sind dies zwei weitere grundlegende Komponenten, [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)die die Bausteine für Abfrageoperationen in MongoDB-Java-Treibern bereitstellen.

Die `Filters` Klasse ist eine Hilfsklasse im MongoDB-Java-Treiber, die eine flüssige API zum Erstellen von Abfragefiltern bereitstellt. Diese Klasse bietet statische Factory-Methoden, die Instanzen von `Bson` Objekten erstellen, die verschiedene Abfragebedingungen repräsentieren. Zu den am häufigsten verwendeten Methoden gehören `eq()` für Gleichheitsvergleiche`gt()`,`lt()`,`gte()`, und `lte()` für numerische Vergleiche `and()` und `or()` für die Kombination mehrerer Bedingungen `in()` sowie `nin()` für Array-Zugehörigkeitstests und `regex()` für den Mustervergleich. Die Klasse ist typsicher konzipiert und bietet im Vergleich zu Abfragen, die auf Rohdokumenten basieren, eine bessere Überprüfung bei der Kompilierung. Daher ist sie der bevorzugte Ansatz für die Erstellung von DocumentDB-Abfragen in Java-Anwendungen. Die Fehlerbehandlung ist robust und bei ungültigen Filterkonstruktionen werden eindeutige Ausnahmen ausgelöst.

`FindIterable`ist eine spezielle Schnittstelle, die für die Verarbeitung des Ergebnisses der `find()` Methode entwickelt wurde. Es bietet eine Vielzahl von Methoden zur Verfeinerung und Steuerung der Abfrageausführung und bietet eine flüssige API für die Methodenverkettung. Die Schnittstelle umfasst grundlegende Methoden zur Änderung von Abfragen, z. B. `limit()` zur Beschränkung der Anzahl der zurückgegebenen Dokumente, `skip()` zur Seitennummerierung, zur Reihenfolge der Ergebnisse, `sort()` zur Auswahl bestimmter Felder und `projection()` zur Indexauswahl. `hint()` Die Batch-, Skip- und Limit-Operationen in `FindIterable` sind wichtige Tools zur Seitennummerierung und Datenverwaltung, mit deren Hilfe gesteuert werden kann, wie Dokumente aus der Datenbank abgerufen und verarbeitet werden.

Batching (`batchSize`) steuert, wie viele Dokumente DocumentDB in einem einzigen Netzwerk-Roundtrip an den Client zurückgibt. Wenn Sie eine Stapelgröße festlegen, gibt DocumentDB nicht alle passenden Dokumente auf einmal zurück, sondern gibt sie in Gruppen mit der angegebenen Stapelgröße zurück. 

Mit Skip können Sie den Startpunkt Ihrer Ergebnisse verschieben und DocumentDB im Wesentlichen anweisen, eine bestimmte Anzahl von Dokumenten zu überspringen, bevor Treffer zurückgegeben werden. Beispielsweise `skip(20)` werden die ersten 20 übereinstimmenden Dokumente umgangen. Dies wird häufig in Paginierungsszenarien verwendet, in denen Sie nachfolgende Ergebnisseiten abrufen möchten. 

Limit schränkt die Gesamtzahl der Dokumente ein, die von einer Abfrage zurückgegeben werden können. Wenn Sie angeben`limit(n)`, beendet DocumentDB die Rückgabe von Dokumenten, nachdem 'n' Dokumente zurückgegeben wurden, auch wenn es mehr Treffer in der Datenbank gibt. 

`FindIterable`unterstützt sowohl Iterator- als auch Cursormuster beim Abrufen von Dokumenten aus Amazon DocumentDB. Der Vorteil der Verwendung `FindIterable` als Iterator besteht darin, dass Dokumente verzögert geladen werden können und Dokumente nur abgerufen werden, wenn sie von der Anwendung angefordert werden. Ein weiterer Vorteil der Verwendung von Iterator besteht darin, dass Sie nicht für die Aufrechterhaltung der Verbindung zum Cluster verantwortlich sind und daher kein explizites Schließen der Verbindung erforderlich ist. 

`FindIterable`bietet auch Unterstützung für [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)die Verwendung von Cursormustern bei der Arbeit mit Amazon DocumentDB DocumentDB-Abfragen. `MongoCursor`ist eine mongoDB-Java-Treiberspezifische Implementierung, die die Kontrolle über Datenbankoperationen und Ressourcenmanagement bietet. Sie implementiert die `AutoCloseable` Schnittstelle und ermöglicht so eine explizite Ressourcenverwaltung über try-with-resources Blöcke, was für das ordnungsgemäße Schließen von Datenbankverbindungen und die Freigabe von Serverressourcen von entscheidender Bedeutung ist. Standardmäßig läuft der Cursor innerhalb von 10 Minuten ab, und DocumentDB bietet Ihnen nicht die Möglichkeit, dieses Timeout-Verhalten zu ändern. Achten Sie bei der Arbeit mit Batchdaten darauf, den nächsten Datenstapel abzurufen, bevor der Cursor das Timeout erreicht. Ein wichtiger Aspekt bei der Verwendung `MongoCursor` ist, dass ein explizites Schließen erforderlich ist, um Ressourcenlecks zu verhindern.

In diesem Abschnitt werden mehrere Beispiele für`find()`, `Filters` und vorgestellt`FindIterable`.

Das folgende Codebeispiel zeigt, wie Sie `find()` mithilfe des Felds „RestaurantID“ ein einzelnes Dokument abrufen können:

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

Die Verwendung `Filters` ermöglicht zwar eine bessere Fehlerprüfung bei der Kompilierung, mit dem Java-Treiber können Sie jedoch auch einen `Bson` Filter direkt in der `find()` Methode angeben. Der folgende Beispielcode übergibt `Bson` das Dokument an`find()`:

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

Der nächste Beispielcode zeigt mehrere Beispiele für die Verwendung der `Filters` Klasse mit`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));
```

Das folgende Beispiel zeigt, wie die Operationen von`sort()`, `skip()``limit()`, und `batchSize()` an einem `FindIterable` Objekt verkettet werden. Die Reihenfolge, in der diese Operationen ausgeführt werden, beeinflusst die Leistung Ihrer Abfrage. Als bewährte Methode sollte die Reihenfolge dieser Operationen`sort()`, `projection()``skip()`, `limit()` und lauten`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);
```

Der folgende Beispielcode zeigt die Erstellung eines Iterators am`FindIterable`. Es verwendet das `forEach` Java-Konstrukt, um die Ergebnismenge zu durchlaufen.

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

Im letzten `find()` Codebeispiel wird gezeigt, wie es zum Abrufen von Dokumenten verwendet `cursor()` wird. Es erstellt den Cursor im Try-Block, wodurch sichergestellt wird, dass der Cursor geschlossen wird, wenn der Code den Try-Block verlässt.

```
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
```

## Aktualisieren vorhandener Dokumente in einer DocumentDB-Sammlung
<a name="updating-documents"></a>

Amazon DocumentDB bietet flexible und leistungsstarke Mechanismen zum Ändern vorhandener Dokumente und zum Einfügen neuer Dokumente, wenn sie nicht existieren. Der MongoDB-Java-Treiber bietet mehrere Methoden für Updates: `updateOne()` für die Aktualisierung einzelner Dokumente, `updateMany()` für die Aktualisierung mehrerer Dokumente und `replaceOne()` für den vollständigen Austausch von Dokumenten. Neben diesen drei Methoden [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)sind, [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), und weitere grundlegende Komponenten, die die Bausteine für Aktualisierungsvorgänge in MongoDB-Java-Treibern bereitstellen. 

Die `Updates` Klasse im MongoDB-Java-Treiber ist eine Hilfsklasse, die statische Factory-Methoden zum Erstellen von Aktualisierungsoperatoren bereitstellt. Sie dient als primärer Builder für die typsichere und lesbare Konstruktion von Aktualisierungsoperationen. Grundlegende Methoden wie `set()``unset()`, und `inc()` ermöglichen die direkte Änderung der Dokumente. Die Leistungsfähigkeit dieser Klasse wird deutlich, wenn mehrere Operationen mit der `Updates.combine()` Methode kombiniert werden, mit der mehrere Aktualisierungsvorgänge atomar ausgeführt werden können, wodurch die Datenkonsistenz gewährleistet wird.

`UpdateOptions`ist eine leistungsstarke Konfigurationsklasse im Java-Treiber von MongoDB, die grundlegende Anpassungsmöglichkeiten für Dokumentaktualisierungsvorgänge bietet. Zwei wichtige Aspekte dieser Klasse sind die Unterstützung von Upsert- und Array-Filtern für Aktualisierungsvorgänge. Die Upsert-Funktion, aktiviert durch`upsert(true)`, ermöglicht die Erstellung neuer Dokumente, wenn während eines Aktualisierungsvorgangs keine passenden Dokumente gefunden werden. Durch `arrayFilters()` den Aktualisierungsvorgang können Array-Elemente, die bestimmte Kriterien erfüllen, präzise aktualisiert werden.

`UpdateResult`Der Java-Treiber von MongoDB bietet den Feedback-Mechanismus, der das Ergebnis eines Aktualisierungsvorgangs detailliert beschreibt. Diese Klasse fasst drei wichtige Kennzahlen zusammen: die Anzahl der Dokumente, die den Aktualisierungskriterien entsprechen (`matchedCount`), die Anzahl der tatsächlich geänderten Dokumente (`modifiedCount`) und Informationen über alle geänderten Dokumente (). `upsertedId` Das Verständnis dieser Metriken ist für die korrekte Fehlerbehandlung, die Überprüfung von Aktualisierungsvorgängen und die Aufrechterhaltung der Datenkonsistenz in Anwendungen unerlässlich.

### Aktualisieren und ersetzen Sie ein einzelnes Dokument
<a name="update-single-doc"></a>

In DocumentDB kann die Aktualisierung eines einzelnen Dokuments mit der Methode updateOne () durchgeführt werden. Diese Methode verwendet einen Filterparameter, der normalerweise von der `Filters` Klasse bereitgestellt wird, um das zu aktualisierende Dokument zu identifizieren, einen `Updat` e-Parameter, der bestimmt, welche Felder aktualisiert werden sollen, und einen optionalen `UpdateOptions` Parameter, um verschiedene Optionen für die Aktualisierung festzulegen. Bei Verwendung `updateOne()` dieser Methode wird nur das erste Dokument aktualisiert, das den Auswahlkriterien entspricht. Der folgende Beispielcode aktualisiert ein einzelnes Feld eines Dokuments:

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

Um mehrere Felder in einem Dokument zu aktualisieren, verwenden Sie `updateOne()` with `Update.combine()` wie im folgenden Beispiel gezeigt. Dieses Beispiel zeigt auch, wie ein Element zu einem Array im Dokument hinzugefügt wird.

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

Das folgende Codebeispiel zeigt, wie ein Dokument in der Datenbank aktualisiert wird. Wenn das angegebene Dokument nicht existiert, wird es stattdessen automatisch als neues Dokument eingefügt. Dieser Code zeigt auch, wie die über das `UpdateResult` Objekt verfügbaren Metriken verwendet werden.

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

Das folgende Codebeispiel zeigt, wie Sie mithilfe der `replaceOne()` Methode ein vorhandenes Dokument vollständig durch ein neues Dokument ersetzen können, anstatt einzelne Felder zu aktualisieren. Die `replaceOne()` Methode überschreibt das gesamte Dokument, wobei nur das `_id` Feld des Originals beibehalten wird. Wenn mehrere Dokumente den Filterkriterien entsprechen, wird nur das zuerst gefundene Dokument ersetzt.

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

### Aktualisieren Sie mehrere Dokumente
<a name="update-multiple-docs"></a>

Es gibt zwei Möglichkeiten, mehrere Dokumente in einer Sammlung gleichzeitig zu aktualisieren. Sie können die `updateMany()` Methode oder die [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)mit der `bulkWrite()` Methode verwenden. Die `updateMany()` Methode verwendet einen Filterparameter, um Dokumente für die Aktualisierung auszuwählen, den `Update` Parameter zur Identifizierung der zu aktualisierenden Felder und einen optionalen `UpdateOptions` Parameter zur Angabe von Aktualisierungsoptionen.

Der folgende Beispielcode demonstriert die Verwendung der `updateMany()` Methode:

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

Der folgende Beispielcode demonstriert die `bulkWrite()` Methode mit demselben Update:

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

## Dokumente aus einer DocumentDB-Sammlung entfernen
<a name="deleting-documents"></a>

Der MongoDB-Java-Treiber bietet `deleteOne()` die Möglichkeit, ein einzelnes Dokument und mehrere Dokumente `deleteMany()` zu entfernen, die bestimmten Kriterien entsprechen. Genau wie beim Aktualisieren kann auch der Löschvorgang mit der `bulkWrite()` Methode verwendet werden. Beides `deleteOne()` und gibt ein [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)Objekt `deleteMany()` zurück, das Informationen über das Ergebnis des Vorgangs enthält, einschließlich der Anzahl der gelöschten Dokumente. Im Folgenden finden Sie ein Beispiel für die Verwendung `deleteMany()` zum Entfernen mehrerer Dokumente:

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

## Fehlerbehandlung mit Wiederholungslogik
<a name="error-handling"></a>

Eine robuste Strategie zur Fehlerbehandlung für Amazon DocumentDB sollte die Kategorisierung von Fehlern in wiederholbare Fehler (wie Netzwerk-Timeouts, Verbindungsprobleme) und nicht wiederholbare Fehler (wie Authentifizierungsfehler, ungültige Abfragen) implementieren. Bei Betriebsfehlern aufgrund von Fehlern, die wiederholt werden sollten, sollte eine Zeitverzögerung zwischen den einzelnen Wiederholungsversuchen sowie die maximale Anzahl von Wiederholungsversuchen vorgesehen werden. Die CRUD-Operationen sollten sich in einem Try-Catch-Block befinden, der Catches [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)und seine Unterklassen enthält. Darüber hinaus sollte es die Überwachung und Protokollierung von Fehlern beinhalten, um die betriebliche Transparenz zu gewährleisten. Im Folgenden finden Sie einen Beispielcode, der zeigt, wie die Behandlung von Wiederholungsfehlern implementiert wird:

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

# Indexverwaltung in Amazon DocumentDB mit Java
<a name="index-management-java"></a>

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.

**Topics**
+ [Erstellen von Indizes](#creating-indexes)
+ [Indizes löschen](#dropping-indes)
+ [Festlegung der Indexauswahl und Bereitstellung eines Indexhinweises](#w2aac43b9b7c17c13)

Amazon DocumentDB unterstützt viele Arten von Indizes. [Einen umfassenden Überblick über alle unterstützten Indizes finden Sie in diesem Blogbeitrag.](https://aws.amazon.com/blogs/database/how-to-index-on-amazon-documentdb-with-mongodb-compatibility/) 

## Indizes mit Java erstellen
<a name="creating-indexes"></a>

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:
+ **[https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Indexes.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Indexes.html)**— 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.
+ **[https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html)**— 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.
+ **[https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexOptions.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexOptions.html)**— 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 unter[Typen der Indexerstellung](managing-indexes.md#index-build-types). Im folgenden Codebeispiel wird [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexOptions.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexOptions.html)ein eindeutiger Index mit dem Namen „unique\$1restaurantID\$1IDX“ im Hintergrund erstellt. Dieses `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 [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html)Objekts und übergibt dann eine Liste von `IndexModel` Objekten an die `createIndexes()` Methode. Das folgende Codebeispiel zeigt, wie ein zusammengesetzter Index mithilfe der [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Indexes.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/Indexes.html)Utility-Klasse erstellt wird. Diese Klasse wird auch verwendet, um anzugeben, ob Sie einen Index mit aufsteigender oder absteigender Sortierreihenfolge erstellen möchten. Nach dem Erstellen mehrerer Indizes überprüft sie die Indexerstellung, indem sie die Methode aufruft. `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 [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/IndexModel.html)für jeden Indextyp ein Index erstellt wird.

```
// 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 [Blogbeitrag](https://aws.amazon.com/blogs/database/unlock-the-power-of-parallel-indexing-in-amazon-documentdb/) bietet eine eingehende Diskussion zur parallel Indizierung. Derzeit unterstützen MongDB-Java-Treiber die Angabe der Worker-Option nicht, wenn Sie `createIndex()` 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
<a name="dropping-indes"></a>

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. [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoCommandException.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/MongoCommandException.html) Der `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
<a name="w2aac43b9b7c17c13"></a>

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 [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ExplainVerbosity.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/ExplainVerbosity.html)Aufzählung verwenden, die den Grad der Ausführlichkeit bestimmt, der von zurückgegeben wird. `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\$1features\$1idx“ 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));
```

# Ereignisgesteuerte Programmierung mit Amazon DocumentDB und Java
<a name="event-driven-programming"></a>

Die ereignisgesteuerte Programmierung im Kontext von Amazon DocumentDB stellt ein leistungsstarkes Architekturmuster dar, bei dem Datenbankänderungen als primäre Ereignisgeneratoren dienen, die nachfolgende Geschäftslogik und -prozesse auslösen. Wenn Datensätze in eine DocumentDB-Auflistung eingefügt, aktualisiert oder gelöscht werden, wirken sich diese Änderungen als Ereignisse aus, die automatisch verschiedene nachgelagerte Prozesse, Benachrichtigungen oder Datensynchronisierungsaufgaben auslösen. Dieses Muster ist besonders nützlich in modernen verteilten Systemen, in denen mehrere Anwendungen oder Dienste in Echtzeit auf Datenänderungen reagieren müssen. Der Hauptmechanismus für die Implementierung ereignisgesteuerter Programmierung in DocumentDB sind Change-Streams.

**Anmerkung**  
In diesem Handbuch wird davon ausgegangen, dass Sie Change-Streams für eine Sammlung aktiviert haben, mit der Sie arbeiten. Weitere Informationen [Change-Streams mit Amazon DocumentDB verwenden](change_streams.md) zum Aktivieren von Change-Streams in der Sammlung finden Sie unter. 

**Arbeiten mit Change-Streams aus der Java-Anwendung**

Die `watch()` Methode im Java-Treiber von MongoDB ist der wichtigste Mechanismus zur Überwachung von Datenänderungen in Echtzeit in Amazon DocumentDB. Die `watch()` Methode kann von Objekten [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoClient.html), und [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html#watch()](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html#watch())aufgerufen werden.

Die `watch()` Methode gibt eine Instanz zurück [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)), die verschiedene Konfigurationsoptionen unterstützt, darunter die vollständige Suche nach Aktualisierungen in Dokumenten, die Bereitstellung von Wiederaufnahmetokens und Zeitstempeln für die Zuverlässigkeit sowie Pipeline-Aggregationsphasen zum Filtern von Änderungen. 

[https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp))implementiert die Java-Kernschnittstelle `Iterable` und kann mit verwendet werden. `forEach()` Um Ereignisse mithilfe von zu erfassen`forEach()`, übergeben Sie eine Callback-Funktion an`forEach()`, die das geänderte Ereignis verarbeitet. Der folgende Codeausschnitt zeigt, wie Sie einen Change-Stream für eine Sammlung öffnen, um die Überwachung von Änderungsereignissen zu starten:

```
ChangeStreamIterable < Document > iterator = collection.watch();
iterator.forEach(event - > {
    System.out.println("Received a change: " + event);
});
```

Eine andere Möglichkeit, alle Änderungsereignisse zu durchlaufen, besteht darin, einen Cursor zu öffnen, der eine Verbindung zum Cluster aufrechterhält und kontinuierlich neue Änderungsereignisse empfängt, sobald sie auftreten. Um einen Change-Streams-Cursor zu erhalten, verwenden Sie die `cursor()` Methode object. [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)) Das folgende Codebeispiel zeigt, wie Änderungsereignisse mithilfe des Cursors überwacht werden:

```
try (MongoChangeStreamCursor < ChangeStreamDocument < Document >> cursor = collection.watch().cursor()) {
    System.out.println(cursor.tryNext());
}
```

Es hat sich bewährt, entweder den [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoChangeStreamCursor.html#getResumeToken()](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/MongoChangeStreamCursor.html#getResumeToken())in einer try-with-resource Anweisung zu erstellen oder den Cursor manuell zu schließen. Beim Aufrufen der `cursor()` Methode on wird eine [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp))zurückgegeben`MongoChangeStreamCursor`, die über einem [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html)Objekt erstellt wurde. 

Die [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html)Klasse ist eine wichtige Komponente, die einzelne Änderungsereignisse im Stream darstellt. Sie enthält detaillierte Informationen zu jeder Änderung, einschließlich des Vorgangstyps (Einfügen, Aktualisieren, Löschen, Ersetzen), des Dokumentschlüssels, der Namespace-Informationen und des vollständigen Dokumentinhalts, sofern verfügbar. Die Klasse bietet Methoden für den Zugriff auf verschiedene Aspekte des Änderungsereignisses, z. B. `getOperationType()` für die Bestimmung der Art der Änderung, für den `getFullDocument()` Zugriff auf den vollständigen Status des Dokuments und `getDocumentKey()` für die Identifizierung des geänderten Dokuments.

Das [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/ChangeStreamDocument.html)Objekt stellt zwei wichtige Informationen bereit: ein Wiederaufnahme-Token und die Uhrzeit des Änderungsereignisses.

Resume-Tokens und zeitbasierte Operationen in DocumentDB-Change-Streams bieten wichtige Mechanismen für die Aufrechterhaltung der Kontinuität und die Verwaltung des Zugriffs auf historische Daten. Ein Resume-Token ist eine eindeutige Kennung, die für jedes Änderungsereignis generiert wird. Sie dient als Lesezeichen, mit dem Anwendungen die Verarbeitung von Change-Streams nach Verbindungsabbrüchen oder Ausfällen an einem bestimmten Punkt wieder aufnehmen können. Wenn ein Change-Stream-Cursor erstellt wird, kann er über `resumeAfter()` diese Option ein zuvor gespeichertes Resume-Token verwenden, sodass der Stream dort weitergeführt werden kann, wo er aufgehört hat, anstatt am Anfang zu beginnen oder Ereignisse zu verlieren.

Zeitbasierte Operationen in Change-Streams bieten unterschiedliche Ansätze, um den Ausgangspunkt der Überwachung von Änderungsereignissen zu verwalten. Mit dieser `startAtOperationTime()` Option können Sie beginnen, Änderungen zu beobachten, die zu oder nach einem bestimmten Zeitstempel vorgenommen wurden. Diese zeitbasierten Funktionen sind besonders nützlich in Szenarien, in denen historische Daten verarbeitet, point-in-time wiederhergestellt oder zwischen Systemen synchronisiert werden müssen.

Im folgenden Codebeispiel wird das Ereignis abgerufen, das mit dem Einfügedokument verknüpft ist, dessen Resume-Token erfasst und dann dieses Token bereitgestellt, um mit der Überwachung auf Ereignisse nach dem Einfügeereignis zu beginnen. Das Ereignis wird dem Aktualisierungsereignis zugeordnet, ruft dann die Clusterzeit ab, zu der die Aktualisierung stattgefunden hat, und verwendet diesen Zeitstempel als Ausgangspunkt für die weitere Verarbeitung.

```
BsonDocument resumeToken;
BsonTimestamp resumeTime;

try (MongoChangeStreamCursor < ChangeStreamDocument < Document >> cursor = collection.watch().cursor()) {
    System.out.println("****************** Insert Document *******************");
    ChangeStreamDocument < Document > insertChange = cursor.tryNext();
    resumeToken = insertChange.getResumeToken();
    printJson(cursor.tryNext());
}
try (MongoChangeStreamCursor < ChangeStreamDocument < Document >> cursor = collection.watch()
    .resumeAfter(resumeToken)
    .cursor()) {
    System.out.println("****************** Update Document *******************");
    ChangeStreamDocument < Document > insertChange = cursor.tryNext();
    resumeTime = insertChange.getClusterTime();
    printJson(cursor.tryNext());
}
try (MongoChangeStreamCursor < ChangeStreamDocument < Document >> cursor = collection.watch()
    .startAtOperationTime(resumeTime)
    .cursor()) {
    System.out.println("****************** Delete Document *******************");
    printJson(cursor.tryNext());
  }
```

Standardmäßig umfasst das Aktualisierungsänderungsereignis nicht das gesamte Dokument und nur die vorgenommenen Änderungen. Wenn Sie auf das gesamte Dokument zugreifen müssen, das aktualisiert wurde, können Sie die `fullDocument()` Methode für das [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp)](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html#startAtOperationTime(org.bson.BsonTimestamp))Objekt aufrufen. Denken Sie daran, dass, wenn Sie bei einem Aktualisierungsereignis die Rückgabe eines vollständigen Dokuments anfordern, das Dokument zurückgegeben wird, das zum Zeitpunkt des Aufrufs der Change-Streams vorhanden war.

Diese Methode verwendet eine [https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/FullDocument.html](https://mongodb.github.io/mongo-java-driver/5.3/apidocs/mongodb-driver-core/com/mongodb/client/model/changestream/FullDocument.html)Aufzählung als Parameter. Derzeit unterstützt Amazon DocumentDB nur DEFAULT und `UPDATE_LOOKUP` Werte. Der folgende Codeausschnitt zeigt, wie Sie das vollständige Dokument für Aktualisierungsereignisse anfordern, wenn Sie beginnen, nach Änderungen zu suchen:

```
try (MongoChangeStreamCursor < ChangeStreamDocument < Document >> cursor = collection.watch().fullDocument(FullDocument.UPDATE_LOOKUP).cursor())
```