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
- Uma conta existente do Azure Cosmos DB.
- Se você tiver uma assinatura do Azure, crie uma nova conta.
- Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
- Como alternativa, você pode experimentar o Azure Cosmos DB gratuitamente antes de confirmar.
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_PROPERTY do 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 n o filho, n-1 o 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 n o filho, n-1 o filho deve estar presente. |