Teilaktualisierung von Dokumenten in Azure Cosmos DB

GILT FÜR: NoSQL

Das Azure Cosmos DB-Feature für die Teilaktualisierung von Dokumenten (auch „Patch-API“) bietet eine praktische Möglichkeit, Dokumente in einem Container zu bearbeiten. Um ein Dokument zu aktualisieren, muss der Client es derzeit lesen, (falls erforderlich) Überprüfungen der optimistischen Gleichzeitigkeitserkennung ausführen, das Dokument lokal aktualisieren und es dann über das Netzwerk als API-Aufruf zum Ersetzen des gesamten Dokuments senden.

Das Feature für die Teilaktualisierung von Dokumenten verbessert diesen Vorgang erheblich. Der Client kann nur die in einem Dokument geänderten Eigenschaften/Felder senden, ohne einen Vorgang zum vollständigen Ersetzen des Dokuments auszuführen. Zu den wichtigsten Vorteilen dieses Features zählen:

  • Verbesserte Entwicklerproduktivität: Die praktische API ist benutzerfreundlich und bietet die Möglichkeit, das Dokument bedingt zu aktualisieren.
  • Leistungsverbesserungen: Das Feature vermeidet zusätzliche CPU-Zyklen auf Clientseite, reduziert die End-to-End-Latenz und erhöht die Netzwerkbandbreite.
  • Schreibvorgänge in mehreren Regionen: Das Feature unterstützt die automatische und transparente Konfliktlösung durch die Teilaktualisierung von diskreten Pfaden innerhalb desselben Dokuments.

Hinweis

Der Vorgang zur teilweisen Dokumentaktualisierung basiert auf dem JSON-Patch-RFC. Eigenschaftsnamen in Pfaden müssen die Zeichen ~ und / als Escapezeichen ~0 bzw ~1. enthalten.

Ein JSON-Beispielzieldokument:

{
  "id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
  "name": "R-410 Road Bicycle",
  "price": 455.95,
  "inventory": {
    "quantity": 15
  },
  "used": false,
  "categoryId": "road-bikes",
  "tags": ["r-series"]
}

Ein JSON-Patchdokument:

[
  { "op": "add", "path": "/color", "value": "silver" },
  { "op": "remove", "path": "/used" },
  { "op": "set", "path": "/price", "value": 355.45 }
  { "op": "incr", "path": "/inventory/quantity", "value": 10 },
  { "op": "add", "path": "/tags/-", "value": "featured-bikes" },
  { "op": "move", "from": "/color", "path": "/inventory/color" }
]

Das resultierende JSON-Dokument:

{
  "id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
  "name": "R-410 Road Bicycle",
  "price": 355.45,
  "inventory": {
    "quantity": 25,
    "color": "silver"
  },
  "categoryId": "road-bikes",
  "tags": ["r-series", "featured-bikes"]
}

Unterstützte Vorgänge

In dieser Tabelle sind die Vorgänge zusammengefasst, die von dieser Funktion unterstützt werden.

Hinweis

Der Zielpfad verweist auf einen Speicherort innerhalb des JSON-Dokuments.

Vorgangsart BESCHREIBUNG
Add (Hinzufügen) Add führt je nach Zielpfad eine der folgenden Schritte aus:
• Wenn im Zielpfad ein Element angegeben wird, das nicht vorhanden ist, wird das Element hinzugefügt.
• Wenn im Zielpfad ein Element angegeben wird, das bereits vorhanden ist, wird sein Wert ersetzt.
• Wenn der Zielpfad einen gültigen Arrayindex darstellt, wird am angegebenen Index ein neues Element in das Array eingefügt. Dadurch werden vorhandene Elemente nach dem neuen Element verschoben.
• Wenn der angegebene Index genauso lang wie das Array ist, wird ein Element an das Array angefügt. Anstatt einen Index anzugeben, können Sie auch das Zeichen - verwenden. Dies führt auch dazu, dass das Element an das Array angefügt wird.
Hinweis: Wird ein Index angegeben, der größer als die Arraylänge ist, führt dies zu einem Fehler.
Set Der Set-Vorgang ähnelt Add, mit der Ausnahme, dass er den Datentyp „Array“ verwendet. Wenn der Zielpfad ein gültiger Arrayindex ist, wird das vorhandene Element an diesem Index aktualisiert.
Replace Der Replace-Vorgang ähnelt Set mit der Ausnahme, dass er einer strikten Semantik zum ausschließlichen Ersetzen folgt. Wenn im Zielpfad ein Element oder ein Array angegeben wird, das nicht vorhanden ist, führt dies zu einem Fehler.
Remove Remove führt je nach Zielpfad eine der folgenden Schritte aus:
• Wenn im Zielpfad ein Element angegeben wird, das nicht vorhanden ist, führt dies zu einem Fehler.
• Wenn im Zielpfad ein Element angegeben wird, das bereits vorhanden ist, wird es entfernt.
• Wenn der Zielpfad ein Arrayindex ist, wird er gelöscht, und alle Elemente über dem angegebenen Index werden um eine Position zurückversetzt.
Hinweis: Wird ein Index angegeben, der gleich oder größer als die Arraylänge ist, führt dies zu einem Fehler.
Increment Dieser Operator erhöht ein Feld um den angegebenen Wert. Er kann sowohl positive als auch negative Werte annehmen. Wenn das Feld nicht vorhanden ist, wird das Feld erstellt und auf den angegebenen Wert festgelegt.
Verschieben Dieser Operator entfernt den Wert an einer angegebenen Position und fügt ihn dem Zielspeicherort hinzu. Das Vorgangsobjekt MUSS einen „from“-Member enthalten, bei dem es sich um eine Zeichenfolge mit einem JSON-Zeigerwert handelt, der auf den Speicherort im Zieldokument verweist, aus dem der Wert verschoben werden soll. Der „from“-Speicherort MUSS vorhanden sein, damit der Vorgang erfolgreich ist. Wenn der „path“-Speicherort ein Objekt vorschlägt, das nicht vorhanden ist, wird das Objekt erstellt und der Wert auf den Wert am „from“-Speicherort festgelegt.
•Wenn der „path“-Speicherort ein Objekt vorschlägt, das bereits vorhanden ist, wird der Wert am „path“-Speicherort durch den Wert am „form“-Speicherort ersetzt.
•Das “path“-Attribut darf kein untergeordnetes JSON-Element des JSON-Speicherorts „from“ sein

Unterstützte Modi

Das Feature für die Teilaktualisierung von Dokumenten unterstützt die folgenden Betriebsmodi. Im Dokument zu den ersten Schritten finden Sie Codebeispiele.

  • Patchen einzelner Dokumente: Sie können ein einzelnes Dokument basierend auf seiner ID und seinem Partitionsschlüssel patchen. Es ist möglich, mehrere Patchvorgänge für ein einzelnes Dokument auszuführen. Der Höchstwert liegt bei 10 Vorgängen.

  • Patches von mehreren Dokumenten: Mehrere Dokumente innerhalb desselben Partitionsschlüssels können im Rahmen einer Transaktion gepatcht werden. Diese Mehrfachdokumenttransaktion wird nur dann committet, wenn alle Vorgänge in der beschriebenen Reihenfolge erfolgreich ausgeführt werden. Schlägt ein Vorgang fehl, wird für die gesamte Transaktion ein Rollback ausgeführt.

  • Bedingte Aktualisierung: Für die oben genannten Modi ist es auch möglich, ein SQL-ähnliches Filterprädikat hinzuzufügen (z. B. from c where c.taskNum = 3), damit der Vorgang fehlschlägt, wenn die im Prädikat angegebene Vorbedingung nicht erfüllt wird.

  • Sie können auch die Massen-APIs unterstützter SDKs verwenden, um mindestens einen Patchvorgang für mehrere Dokumente auszuführen.

Ähnlichkeiten und Unterschiede

Vergleichen wir die Gemeinsamkeiten und Unterschiede zwischen den unterstützten Modi.

„Add“ im Vergleich zu „Set“

Der Set-Vorgang ähnelt Add für alle Datentypen mit Ausnahme von Array. Ein Add-Vorgang an einem beliebigen (gültigen) Index führt dazu, dass am angegebenen Index ein Element hinzugefügt wird und dass alle vorhandenen Elemente im Array an Positionen nach dem vorhandenen Element verschoben werden. Dieses Verhalten steht im Gegensatz zu einem Set-Vorgang, bei dem das vorhandene Element am angegebenen Index aktualisiert wird.

„Add“ im Vergleich zu „Replace“

Ein Add-Vorgang fügt eine Eigenschaft hinzu, wenn sie noch nicht vorhanden ist (einschließlich des Datentyps Array). Der Replace-Vorgang schlägt fehl, wenn die Eigenschaft nicht vorhanden ist (dies gilt auch für den Datentyp Array).

„Set“ im Vergleich zu „Replace“

Ein Set-Vorgang fügt eine Eigenschaft hinzu, wenn sie noch nicht vorhanden ist (außer bei Array-Datentypen). Der Replace-Vorgang schlägt fehl, wenn die Eigenschaft nicht vorhanden ist (dies gilt auch für den Datentyp Array).

Hinweis

Replace ist ein guter Kandidat, bei dem Benutzer*innen erwarten, dass einige der Eigenschaften immer vorhanden sind, und ermöglicht es Ihnen, dies durchzusetzen/zu erzwingen.

REST-API-Referenz für Teilaktualisierung von Dokumenten

Die Azure Cosmos DB REST-API bietet programmgesteuerten Zugriff auf Azure Cosmos DB-Ressourcen zum Erstellen, Abfragen und Löschen von Datenbanken, Dokumentsammlungen und Dokumenten. Sie können nicht nur Vorgänge zum Einfügen, Ersetzen, Löschen, Lesen, Enumerieren und Abfragen für JSON-Dokumente in einer Sammlung ausführen, sondern auch die HTTP-Methode PATCH für die Teilaktualisierung von Dokumenten verwenden. Weitere Informationen finden Sie in der Azure Cosmos DB REST-API-Referenz.

So sieht beispielsweise die Anforderung für einen set-Vorgang mit einer Teilaktualisierung des Dokuments aus.

PATCH https://querydemo.documents.azure.com/dbs/FamilyDatabase/colls/FamilyContainer/docs/Andersen.1 HTTP/1.1
x-ms-documentdb-partitionkey: ["Andersen"]
x-ms-date: Tue, 29 Mar 2016 02:28:29 GMT
Authorization: type%3dmaster%26ver%3d1.0%26sig%3d92WMAkQv0Zu35zpKZD%2bcGSH%2b2SXd8HGxHIvJgxhO6%2fs%3d
Content-Type:application/json_patch+json
Cache-Control: no-cache
User-Agent: Microsoft.Azure.DocumentDB/2.16.12
x-ms-version: 2015-12-16
Accept: application/json
Host: querydemo.documents.azure.com
Cookie: x-ms-session-token#0=602; x-ms-session-token=602
Content-Length: calculated when request is sent
Connection: keep-alive
{
  "operations": [
    {
      "op": "set",
      "path": "/Parents/0/FamilyName",
      "value": "Bob"
    }
  ]
}

Konfliktlösung auf Dokument- und Pfadebene im Vergleich

Wenn Ihr Azure Cosmos DB-Konto mit mehreren Schreibregionen konfiguriert ist, gelten Konflikt- und Konfliktlösungsrichtlinien auf Dokumentebene, bei denen das Prinzip „Letzter Schreibvorgang gewinnt“ (Last Write Wins, LWW) die Standardrichtlinie für die Konfliktlösung darstellt. Bei der Teilaktualisierung von Dokumenten erkennen und lösen Patchvorgänge in mehreren Regionen Konflikte auf einer tieferen Pfadebene.

Die Konfliktauflösung lässt sich anhand eines Beispiels besser verdeutlichen.

Angenommen, Sie verfügen über das folgende Dokument in Azure Cosmos DB:

{
  "id": 1,
  "name": "John Doe",
  "email": "jdoe@contoso.com",
  "phone": ["12345", "67890"],
  "level": "gold"
}

Verschiedene Clients führen Patchvorgänge gleichzeitig in verschiedenen Regionen aus:

  • Set attribute /level to platinum
  • Remove 67890 from /phone

Abbildung, die die Konfliktlösung bei gleichzeitigen Teilaktualisierungen in mehreren Regionen zeigt

Da Patchanforderungen an Pfade innerhalb des Dokuments gestellt wurden, die keinen Konflikt verursachen, werden diese Konflikte in diesen Anforderungen automatisch und transparent aufgelöst (im Gegensatz zum LWW-Prinzip (Last Writer Wins) auf Dokumentebene).

Dem Client sieht nach der Konfliktlösung das folgende Dokument:

{
  "id": 1,
  "name": "John Doe",
  "email": "jdoe@contoso.com",
  "phone": ["12345"],
  "level": "platinum"
}

Hinweis

Falls eine Eigenschaft eines Dokuments gleichzeitig in mehreren Regionen gepatcht wird, gelten die regulären Konfliktlösungsrichtlinien.

Änderungsfeed

Der Änderungsfeed in Azure Cosmos DB überwacht alle Änderungen in einem Container und gibt dann Dokumente aus, die geändert wurden. Mithilfe des Änderungsfeeds werden alle Updates für Dokumente angezeigt, einschließlich teilweiser und vollständiger Dokumentaktualisierungen. Wenn Sie Elemente aus dem Änderungsfeed verarbeiten, wird das vollständige Dokument auch dann zurückgegeben, wenn die Aktualisierung das Ergebnis eines Patchvorgangs war.

Weitere Informationen zum Änderungsfeed in Azure Cosmos DB finden Sie unter Änderungsfeed in Azure Cosmos DB.

Nächste Schritte

  • Erfahren Sie, wie Sie mit der Teilaktualisierung von Dokumenten in .NET, Java und Node beginnen.
  • Häufig gestellte Fragen zur Teilaktualisierung von Dokumenten