Partilhar via


Introdução à Atualização Parcial de Documentos do Azure Cosmos DB

APLICA-SE A: NoSQL

Este artigo fornece exemplos que ilustram como usar a Atualização Parcial de Documentos com SDKs .NET, Java e Node. Ele também descreve erros comuns que você pode encontrar.

Este artigo contém links para exemplos de código para os seguintes cenários:

  • Executar uma única operação de patch
  • Combine várias operações de patch
  • Usar sintaxe de patch condicional com base no predicado de filtro
  • Executar operação de patch como parte de uma transação

Pré-requisitos

O suporte para Atualização Parcial de Documentos (API de Patch) no SDK do Azure Cosmos DB .NET v3 está disponível a partir da versão 3.23.0. Você pode baixá-lo da Galeria NuGet.

Nota

Encontre um exemplo completo de Atualização Parcial de Documentos no repositório de exemplos do .NET v3 no GitHub.

  • Execute uma única operação de patch:

    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;
    
  • Combine várias operações de patch:

    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
    );
    
  • Use a sintaxe do patch condicional com base no predicado do filtro:

    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
    );
    
  • Execute a operação de patch como parte de uma transação:

    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;
    

Suporte para programação do lado do servidor

As operações de Atualização Parcial de Documentos também podem ser executadas no lado do servidor usando procedimentos armazenados, gatilhos e funções definidas pelo usuário.

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

Nota

Encontre a definição de validateOptionsAndCallback no .js DocDbWrapperScript no GitHub.

Exemplo de procedimento armazenado para operação de patch:

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

Resolução de Problemas

Aqui estão alguns erros comuns que você pode encontrar ao usar esse recurso:

Mensagem de Erro Descrição
Solicitação de patch inválida: verifique a sintaxe da especificação do patch. A sintaxe da operação de correção é inválida. Para obter mais informações, consulte a especificação Atualização parcial de documentos.
Solicitação de patch inválida: Não é possível corrigir a propriedade SYSTEM_PROPERTYdo sistema . Propriedades geradas pelo sistema como _id, _ts, _etag, _rid não são modificáveis usando uma operação de patch. Para obter mais informações, consulte Perguntas frequentes sobre atualização parcial de documentos.
O número de operações de patch não pode exceder 10. Há um limite de 10 operações de patch que podem ser adicionadas em uma única especificação de patch. Para obter mais informações, consulte Perguntas frequentes sobre atualização parcial de documentos.
Para Operation(PATCH_OPERATION_INDEX): Index(ARRAY_INDEX) para operar está fora dos limites da matriz. O índice do elemento de matriz a ser corrigido está fora dos limites.
Para Operation(PATCH_OPERATION_INDEX)): Node(PATH) a ser substituído foi removido anteriormente na transação. O caminho que você está tentando corrigir não existe.
Para Operation(PATCH_OPERATION_INDEX): Node(PATH) a ser removido está ausente. Nota: também pode ter sido removido anteriormente na transação.  O caminho que você está tentando corrigir não existe.
Para Operation(PATCH_OPERATION_INDEX): Node(PATH) a ser substituído está ausente. O caminho que você está tentando corrigir não existe.
Para Operation(PATCH_OPERATION_INDEX): Node(PATH) não é um número. A operação de incremento só pode funcionar em inteiros e flutuantes. Para obter mais informações, consulte: Operações suportadas.
Para Operation(PATCH_OPERATION_INDEX): Add Operation só pode criar um objeto filho de um nó existente (matriz ou objeto) e não pode criar caminho recursivamente, nenhum caminho encontrado além: PATH. Os caminhos filho podem ser adicionados a um tipo de objeto ou nó de matriz. Além disso, para criar no filho, n-1o filho deve estar presente.
Para Operation(PATCH_OPERATION_INDEX): Given Operation só pode criar um objeto filho de um nó existente (matriz ou objeto) e não pode criar caminho recursivamente, nenhum caminho encontrado além: PATH. Os caminhos filho podem ser adicionados a um tipo de objeto ou nó de matriz. Além disso, para criar no filho, n-1o filho deve estar presente.

Próximos passos