Introducción a la actualización parcial de documentos de Azure Cosmos DB
SE APLICA A: NoSQL
En este artículo se proporciona un ejemplo que ilustra el uso de la actualización parcial de documentos con los SDK de .NET, Java y Node. También se describen los errores comunes que podría encontrar.
En este artículo se incluyen vínculos a ejemplos de código para los escenarios siguientes:
- Ejecución de una sola operación de revisión
- Combinación de varias operaciones de revisión
- Uso de la sintaxis de revisión condicional basada en el predicado del filtro
- Ejecución de la operación de revisión como parte de una transacción
Requisitos previos
- Una cuenta existente de Azure Cosmos DB.
- Si tiene una suscripción de Azure, cree una nueva cuenta.
- Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
- Como alternativa, puede probar Azure Cosmos DB gratis antes de confirmarlo.
El soporte para la actualización parcial de documentos (API de revisiones) en el SDK de Azure Cosmos DB .NET v3 está disponible a partir de la versión 3.23.0. Puede descargarlo desde la galería de NuGet.
Nota:
Se puede encontrar un ejemplo completo de una actualización parcial de documentos en el repositorio de ejemplos de .NET v3 en GitHub.
Ejecutar una sola operación de revisión:
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;
Combinar varias operaciones de revisión:
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 );
Usar la sintaxis de revisión condicional basada en el predicado del 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 );
Ejecutar la operación de revisión como parte de una transacción:
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;
Compatibilidad con la programación en el lado servidor
Las operaciones de actualización parcial de documentos también pueden ejecutarse en el lado servidor utilizando procedimientos almacenados, desencadenadores y funciones definidas por el usuario.
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:
Busque la definición de validateOptionsAndCallback
en el .js DocDbWrapperScript en GitHub.
Procedimiento almacenado de ejemplo para la operación de revisión:
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.");
}
Solución de problemas
Esta es una lista de errores comunes que puede encontrar al usar esta característica:
Mensaje de error | Descripción |
---|---|
Solicitud de revisión no válida: compruebe la sintaxis de la especificación de revisión. | La sintaxis de la operación de revisión no es válida. Para más información, consulte la especificación de la actualización parcial de documentos. |
Invalid patch request: Can't patch system property SYSTEM_PROPERTY . |
Las propiedades generadas por el sistema como _id , _ts , _etag y _rid no se pueden modificar mediante una operación de revisión. Para más información, consulte Preguntas más frecuentes sobre la actualización parcial de documentos. |
El número de operaciones de revisión no puede superar 10. | Hay un límite de 10 operaciones de revisión que se pueden agregar en una única especificación de revisión. Para más información, consulte Preguntas más frecuentes sobre la actualización parcial de documentos. |
Para la operación (PATCH_OPERATION_INDEX ): el índice (ARRAY_INDEX ) en el que se opera está fuera de los límites de matriz. |
El índice del elemento de matriz al que se va a aplicar la revisión está fuera de los límites. |
Para la operación (PATCH_OPERATION_INDEX ): el nodo(PATH ) que se va a sustituir se ha eliminado anteriormente en la operación. |
La ruta de acceso que intenta aplicar a la revisión no existe. |
Para la operación (PATCH_OPERATION_INDEX ): el nodo (PATH ) que se va a quitar no está presente. Nota: es posible que también se haya quitado anteriormente en la transacción. |
La ruta de acceso que intenta aplicar a la revisión no existe. |
Para la operación (PATCH_OPERATION_INDEX ): el nodo (PATH ) que se va a reemplazar no está presente. |
La ruta de acceso que intenta aplicar a la revisión no existe. |
For Operation(PATCH_OPERATION_INDEX ): Node(PATH ) isn't a number. |
La operación de incremento solo puede funcionar en enteros y flotantes. Para más información, consulte: Operaciones compatibles. |
Para la operación (PATCH_OPERATION_INDEX ): la adición de una operación solo puede crear un objeto secundario de un nodo existente (matriz u objeto) y no puede crear la ruta de acceso de forma recursiva. No se encontró ninguna ruta de acceso más allá de: PATH . |
Las rutas de acceso secundarias se pueden agregar a un tipo de nodo de objeto o matriz. Además, para crear el n er elemento secundario, debe estar presente el n-1 do elemento secundario. |
For Operation(PATCH_OPERATION_INDEX ): Given Operation can only create a child object of an existing node(array or object) and can't create path recursively, no path found beyond: PATH . |
Las rutas de acceso secundarias se pueden agregar a un tipo de nodo de objeto o matriz. Además, para crear el n er elemento secundario, debe estar presente el n-1 do elemento secundario. |