Начало работы с частичным обновлением документов в Azure Cosmos DB
ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL
В этой статье приведены примеры использования частичного обновления документов с пакетами SDK для .NET, Java и Node. В нем также описываются распространенные ошибки, которые могут возникнуть.
В этой статье приводятся ссылки на примеры кода для следующих сценариев:
- Выполнение одной операции исправления
- Объединение нескольких операций исправления
- Использование синтаксиса условного исправления на основе предиката фильтра
- Выполнение операции исправления в рамках транзакции
Необходимые компоненты
- Существующая учетная запись Azure Cosmos DB.
- Если у вас есть подписка Azure, создайте новую учетную запись.
- Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе.
- Кроме того, перед фиксацией можно воспользоваться бесплатной службой Azure Cosmos DB.
Поддержка частичного обновления документов (API исправлений) в пакете SDK для .NET для .NET для Azure Cosmos DB версии 3 доступна начиная с версии 3.23.0. Его можно скачать из коллекции NuGet.
Примечание.
Найдите полный пример частичного обновления документов в репозитории примеров .NET версии 3 на GitHub.
Выполните одну операцию исправления:
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;
Объединение нескольких операций исправления:
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 );
Используйте синтаксис условного исправления на основе предиката фильтра:
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 );
Выполните операцию исправления в рамках транзакции:
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;
Поддержка программирования на стороне сервера
Операции частичного обновления документов также можно выполнять на стороне сервера с помощью хранимых процедур, триггеров и пользовательских функций.
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;
}
}
}
);
};
Примечание.
Найдите определение validateOptionsAndCallback
в .js DocDbWrapperScript на сайте GitHub.
Пример хранимой процедуры для операции исправления:
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.");
}
Устранение неполадок
Ниже приведены некоторые распространенные ошибки, которые могут возникнуть при использовании этой функции:
Сообщение об ошибке | Description |
---|---|
Недопустимый запрос на исправление: проверьте синтаксис спецификации исправлений. | Недопустимый синтаксис операции исправления. Дополнительные сведения см . в спецификации частичного обновления документов. |
Неверный запрос исправления: не удается исправить системное свойство SYSTEM_PROPERTY . |
Системные свойства, такие как _id , _ts _etag не _rid изменяются с помощью операции исправления. Дополнительные сведения см. в часто задаваемых вопросы о частичном обновлении документов. |
Количество операций исправления не может превышать 10. | В отдельной спецификации исправления можно добавить не более 10 операций исправления. Дополнительные сведения см. в часто задаваемых вопросы о частичном обновлении документов. |
Для operation(): Index(PATCH_OPERATION_INDEX ARRAY_INDEX ) для работы находится вне границ массива. |
Индекс элемента массива, который требуется исправить, выходит за рамки. |
Для операция(PATCH_OPERATION_INDEX )): заменяемый узел(PATH ) был удален ранее при выполнении транзакции. |
Путь, по которому вы пытаетесь установить исправление, не существует. |
Для операция(PATCH_OPERATION_INDEX ): отсутствует удаляемый узел(PATH ). Примечание. Возможно, она также была удалена ранее в транзакции. |
Путь, по которому вы пытаетесь установить исправление, не существует. |
Для операция(PATCH_OPERATION_INDEX ): отсутствует заменяемый узел(PATH ). |
Путь, по которому вы пытаетесь установить исправление, не существует. |
Для операции PATCH_OPERATION_INDEX : узел PATH не является числом. |
Операция приращения работает только для целых чисел и чисел с плавающей точкой. Дополнительные сведения см. в статье "Поддерживаемые операции". |
Для Operation(PATCH_OPERATION_INDEX ): Добавление операции может создавать только дочерний объект существующего узла (массива или объекта) и не может создавать путь рекурсивно, ни путь не найден за пределами: PATH |
Пути дочерних элементов можно добавить к типу узла объекта или массива. Кроме того, чтобы создать n дочерний элемент, n-1 должен присутствовать его дочерний элемент. |
Для операции PATCH_OPERATION_INDEX : указанная операция может только создать дочерний объект существующего узла (массива или объекта) и не может создать путь рекурсивно. Не найден путь после PATH . |
Пути дочерних элементов можно добавить к типу узла объекта или массива. Кроме того, чтобы создать n дочерний элемент, n-1 должен присутствовать его дочерний элемент. |