開始使用 Azure Cosmos DB 部分文件更新
適用於:NoSQL
本文提供的範例說明如何在 .NET、Java、Node SDK 中使用部分文件更新。 文中亦描述您可能會遇到的常見錯誤。
本文連結至下列案例的程式碼範例:
- 執行單一修補作業
- 結合多個修補作業
- 使用以篩選述詞為基礎的條件式修補程式語法
- 在交易中執行修補作業
必要條件
- 現有的 Azure Cosmos DB 帳戶。
- 如果您有 Azure 訂用帳戶,則請建立新的帳戶。
- 如尚未擁有 Azure 訂用帳戶,請在開始之前先建立免費帳戶。
- 或者,您可以在認可之前免費試用 Azure Cosmos DB。
Azure Cosmos DB .NET v3 SDK 從 3.23.0 版起支援部分文件更新 (修補 API)。 您可以從 NuGet 資源庫下載此 SDK。
注意
您可以在 GitHub 的 .NET v3 範例存放庫中找到完整的部分文件更新範例。
執行單一修補作業:
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;
}
}
}
);
};
注意
在 GitHub 上的 .js DocDbWrapperScript 中尋找 validateOptionsAndCallback
的定義。
修補作業的範例預存程序:
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.");
}
疑難排解
以下是您使用此功能時可能遇到的一些常見錯誤:
錯誤訊息 | 說明 |
---|---|
修補要求無效:檢查修補規格的語法。 | 修補作業語法無效。 如需詳細資訊,請參閱部分文件更新規格。 |
修補要求無效:無法修補系統屬性 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 個子系必須存在。 |
對於作業 (PATCH_OPERATION_INDEX ):「給定作業」只能建立現有節點 (陣列或物件) 的子物件,無法遞迴建立路徑,在 PATH 以外找不到路徑。 |
子路徑可以新增至物件或陣列節點類型。 此外,若要建立第 n 個子系,則第 n-1 個子系必須存在。 |