Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приведены примеры использования частичного обновления документов с пакетами SDK для .NET, Java и Node. В нем также описываются распространенные ошибки, которые могут возникнуть.
В этой статье приводятся ссылки на примеры кода для следующих сценариев:
- Выполнение одной операции исправления
- Объединение нескольких операций исправления
- Использование синтаксиса условного патча на основе предиката фильтра
- Выполнение операции исправления в рамках транзакции
Prerequisites
- Существующая учетная запись Azure Cosmos DB.
- Если у вас есть подписка Azure, создайте новую учетную запись.
- Если у вас нет подписки на Azure, создайте бесплатную учетную запись перед началом.
Использование частичного обновления документов
Поддержка частичного обновления документов (Patch API) в пакете SDK для .NET для Azure Cosmos DB доступна в версии 3.23.0 и более поздних версий. Пакет можно скачать из коллекции NuGet.
Note
Найдите полный пример частичного обновления документов в репозитории примеров .NET версии 3 на GitHub.
Выполните одну операцию исправления:
ItemResponse<Product> response = await container.PatchItemAsync<Product>( id: "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", 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: "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", 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: "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", 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: "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", patchOperations: operations, requestOptions: options ); batch.PatchItem( id: "f5f5f5f5-aaaa-bbbb-cccc-d6d6d6d6d6d6", 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;
}
}
}
);
};
Note
Найдите определение 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.");
}
Troubleshooting
Ниже приведены некоторые распространенные ошибки, которые могут возникнуть при использовании этой функции:
| Сообщение об ошибке | Description |
|---|---|
| Недопустимый запрос на исправление: проверьте синтаксис спецификации исправлений. | Недопустимый синтаксис операции патча. Дополнительные сведения см. в спецификации. |
Неверный запрос исправления: не удается исправить системное свойство SYSTEM_PROPERTY. |
Системные свойства, такие как _id, _ts, _etag, _rid, не могут быть изменены с помощью операции патча. Дополнительные сведения см. в разделе часто задаваемых вопросов о частичном обновлении документов. |
| Количество операций исправления не может превышать 10. | В отдельной спецификации исправления можно добавить не более 10 операций исправления. Дополнительные сведения см. в разделе часто задаваемых вопросов о частичном обновлении документов. |
Для операции (PATCH_OPERATION_INDEX): индекс (ARRAY_INDEX), на котором должно выполняться действие, находится вне границ массива. |
Индекс элемента массива, который требуется исправить, выходит за пределы допустимого диапазона. |
Для операции(PATCH_OPERATION_INDEX): Узел(PATH), который должен быть заменен, был удален ранее в транзакции. |
Попытка использовать указанный вами путь для исправления не удалась, так как он не существует. |
Для операции(PATCH_OPERATION_INDEX): отсутствует узел(PATH), который должен быть удален. Примечание. Возможно, она также была удалена ранее в транзакции. |
Попытка использовать указанный вами путь для исправления не удалась, так как он не существует. |
Для операции(PATCH_OPERATION_INDEX): заменяемый узел(PATH) отсутствует. |
Попытка использовать указанный вами путь для исправления не удалась, так как он не существует. |
Для операции PATCH_OPERATION_INDEX: узел PATH не является числом. |
Операция приращения работает только для целых чисел и чисел с плавающей точкой. Дополнительные сведения см. в разделе "Поддерживаемые операции". |
Для операции добавления (PATCH_OPERATION_INDEX): Операция добавления может создавать только дочерний объект существующего узла (массива или объекта) и не может создавать путь рекурсивно; никакой путь не найден за пределами: PATH. |
Пути дочерних элементов можно добавить к типу узла объекта или массива. Кроме того, чтобы создать n-й дочерний элемент, должен присутствовать n-1-й дочерний элемент. |
Для Operation(PATCH_OPERATION_INDEX): Данная операция может создавать только дочерний объект существующего узла (массива или объекта) и не может рекурсивно создавать путь, пути за пределами PATH не найдены. |
Пути дочерних элементов можно добавить к типу узла объекта или массива. Кроме того, чтобы создать n-й дочерний элемент, должен присутствовать n-1-й дочерний элемент. |