Freigeben über


Erste Schritte mit der Teilaktualisierung von Dokumenten in Azure Cosmos DB

GILT FÜR: NoSQL

Dieser Artikel enthält Beispiele, welche die Verwendung der Teilaktualisierung von Dokumenten mit .NET-, Java- und Node-SDKs illustrieren. Außerdem werden häufige Fehler beschrieben, die auftreten können.

Dieser Artikel enthält Links zu Codebeispielen für die folgenden Szenarien:

  • Ausführen eines einzelnen Patchvorgangs
  • Kombinieren mehrerer Patchvorgänge
  • Verwenden der bedingten Patchsyntax basierend auf dem Filterprädikat
  • Ausführen eines Patchvorgangs als Teil einer Transaktion

Voraussetzungen

Unterstützung für die Teilaktualisierung von Dokumenten (Patch-API) im Azure Cosmos DB .NET v3-SDK ist ab Version 3.23.0 verfügbar. Sie können sie aus dem NuGet-Katalog herunterladen.

Hinweis

Ein vollständige Beispiel für eine Teilaktualisierung eines Dokuments finden Sie im Repository für .NET v3-Beispiele auf GitHub.

  • Ausführen eines einzelnen Patchvorgangs:

    ItemResponse<Product> response = await container.PatchItemAsync<Product>(
        id: "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
        partitionKey: new PartitionKey("road-bikes"),
        patchOperations: new[] {
            PatchOperation.Replace("/price", 355.45)
        }
    );
    
    Product updated = response.Resource;
    
  • Kombinieren mehrerer Patchvorgänge:

    List<PatchOperation> operations = new ()
    {
        PatchOperation.Add("/color", "silver"),
        PatchOperation.Remove("/used"),
        PatchOperation.Increment("/price", 50.00),
        PatchOperation.Add("/tags/-", "featured-bikes")
    };
    
    ItemResponse<Product> response = await container.PatchItemAsync<Product>(
        id: "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
        partitionKey: new PartitionKey("road-bikes"),
        patchOperations: operations
    );
    
  • Verwenden der bedingten Patchsyntax basierend auf dem Filterprädikat:

    PatchItemRequestOptions options = new()
    {
        FilterPredicate = "FROM products p WHERE p.used = false"
    };
    
    List<PatchOperation> operations = new ()
    {
        PatchOperation.Replace($"/price", 100.00),
    };
    
    ItemResponse<Product> response = await container.PatchItemAsync<Product>(
        id: "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
        partitionKey: new PartitionKey("road-bikes"),
        patchOperations: operations,
        requestOptions: options
    );
    
  • Ausführen eines Patchvorgangs als Teil einer Transaktion:

    TransactionalBatchPatchItemRequestOptions options = new()
    {
        FilterPredicate = "FROM products p WHERE p.used = false"
    };
    
    List<PatchOperation> operations = new ()
    {
        PatchOperation.Add($"/new", true),
        PatchOperation.Remove($"/used")
    };
    
    TransactionalBatch batch = container.CreateTransactionalBatch(
        partitionKey: new PartitionKey("road-bikes")
    );
    batch.PatchItem(
        id: "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
        patchOperations: operations,
        requestOptions: options
    );
    batch.PatchItem(
        id: "892f609b-8885-44df-a9ed-cce6c0bd2b9e",
        patchOperations: operations,
        requestOptions: options
    );
    
    TransactionalBatchResponse response = await batch.ExecuteAsync();
    bool success = response.IsSuccessStatusCode;
    

Unterstützung für die serverseitige Programmierung

Vorgänge für die Teilaktualisierung von Dokumenten können mithilfe von gespeicherten Prozeduren, Triggern und benutzerdefinierten Funktionen auch serverseitig ausgeführt werden.

this.patchDocument = function (documentLink, patchSpec, options, callback) {
    if (arguments.length < 2) {
        throw new Error(ErrorCodes.BadRequest, sprintf(errorMessages.invalidFunctionCall, 'patchDocument', 2, arguments.length));
    }
    if (patchSpec === null || !(typeof patchSpec === "object" || Array.isArray(patchSpec))) {
        throw new Error(ErrorCodes.BadRequest, errorMessages.patchSpecMustBeObjectOrArray);
    }

    var documentIdTuple = validateDocumentLink(documentLink, false);
    var collectionRid = documentIdTuple.collId;
    var documentResourceIdentifier = documentIdTuple.docId;
    var isNameRouted = documentIdTuple.isNameRouted;

    patchSpec = JSON.stringify(patchSpec);
    var optionsCallbackTuple = validateOptionsAndCallback(options, callback);

    options = optionsCallbackTuple.options;
    callback = optionsCallbackTuple.callback;

    var etag = options.etag || '';
    var indexAction = options.indexAction || '';

    return collectionObjRaw.patch(
        collectionRid,
        documentResourceIdentifier,
        isNameRouted,
        patchSpec,
        etag,
        indexAction,
        function (err, response) {
            if (callback) {
                if (err) {
                    callback(err);
                } else {
                    callback(undefined, JSON.parse(response.body), response.options);
                }
            } else {
                if (err) {
                    throw err;
                }
            }
        }
    );
}; 

Hinweis

Suchen Sie die Definition von validateOptionsAndCallback im .js DocDbWrapperScript auf GitHub.

Beispiel für eine gespeicherte Prozedur für den Patchvorgang:

function patchDemo() {
    var doc = {
        "id": "exampleDoc",
        "fields": {
            "field1": "exampleString",
            "field2": 20,
            "field3": 40
        }
    };
    
    var isAccepted = __.createDocument(__.getSelfLink(), doc, (err, doc) => {
        if (err) {
            throw err;
        }
        else {
            getContext().getResponse().setBody("Example document successfully created.");
            
            var patchSpec = [
                { "op": "add", "path": "/fields/field1", "value": "newExampleString" },
                { "op": "remove", "path": "/fields/field2" },
                { "op": "incr", "path": "/fields/field3", "value": 10 }
            ];
            
            var isAccepted = __.patchDocument(doc._self, patchSpec, (err, doc) => {
                if (err) {
                    throw err;
                }
                else {
                    getContext().getResponse().appendBody(" Example document successfully patched.");
                }
            });
            
            if (!isAccepted) throw new Error("Patch wasn't accepted");
        }
    });

    if (!isAccepted) throw new Error("Create wasn't accepted.");
}

Problembehandlung

Hier sind einige häufiger Fehler, die bei der Verwendung dieses Features auftreten können:

Fehlermeldung Beschreibung
Ungültige Patchanforderung: Überprüfen Sie die Syntax der Patchspezifikation. Die Syntax des Patchvorgangs ist ungültig. Weitere Informationen finden Sie in der Spezifikation der Teilaktualisierung von Dokumenten.
Ungültige Patchanforderung: Die Systemeigenschaft SYSTEM_PROPERTY kann nicht gepatcht werden. Systemgenerierte Eigenschaften wie _id, _ts, _etag und _rid können nicht mit einem Patchvorgang geändert werden. Weitere Informationen finden Sie unter Häufig gestellte Fragen zur Teilaktualisierung von Dokumenten.
Die Anzahl der Patchvorgänge darf 10 nicht überschreiten. Es gibt ein Limit von 10 Patchvorgängen, die in einer einzelnen Patchspezifikation hinzugefügt werden können. Weitere Informationen finden Sie unter Häufig gestellte Fragen zur Teilaktualisierung von Dokumenten.
Für Vorgang(PATCH_OPERATION_INDEX): Der Index(ARRAY_INDEX), für den der Vorgang ausgeführt werden soll, liegt außerhalb der Arraygrenzen. Der Index des Arrayelements, das gepatcht werden soll, liegt außerhalb der Grenzen.
Für Operation(PATCH_OPERATION_INDEX): Der zu ersetzende Node(PATH) wurde zuvor in der Transaktion entfernt. Der Pfad, den Sie patchen möchten, ist nicht vorhanden.
Für Operation(PATCH_OPERATION_INDEX): Der zu entfernende Node(PATH) ist nicht vorhanden. Hinweis: Möglicherweise wurde er auch früher in der Transaktion entfernt.  Der Pfad, den Sie patchen möchten, ist nicht vorhanden.
Für Operation(PATCH_OPERATION_INDEX): Der zu entfernende Node(PATH) ist nicht vorhanden. Der Pfad, den Sie patchen möchten, ist nicht vorhanden.
Für Operation(PATCH_OPERATION_INDEX): Node(PATH) ist nicht numerisch. Der Inkrementvorgang kann nur für ganze Zahlen und Gleitkommazahlen verwendet werden. Weitere Informationen finden Sie unter Unterstützte Vorgänge.
Für Vorgang(PATCH_OPERATION_INDEX): Der Vorgang „Hinzufügen“ kann nur ein untergeordnetes Objekt eines vorhandenen Knotens (Array oder Objekt) erstellen und kann nicht rekursiv einen Pfad erstellen. Es wurde kein Pfad nach PATH gefunden. Untergeordnete Pfade können einem Objekt- oder Arrayknotentyp hinzugefügt werden. Außerdem sollte zum Erstellen des untergeordneten Elements n das untergeordnete Element n-1vorhanden sein.
Für Operation(PATCH_OPERATION_INDEX): Mit einem angegebenen Vorgang kann nur ein untergeordnetes Objekt eines vorhandenen Knotens (Array oder Objekt) erstellt werden, und das rekursive Erstellen eines Pfads ist nicht möglich. Es wurde kein Pfad nach PATH gefunden. Untergeordnete Pfade können einem Objekt- oder Arrayknotentyp hinzugefügt werden. Außerdem sollte zum Erstellen des untergeordneten Elements n das untergeordnete Element n-1vorhanden sein.

Nächste Schritte