Azure Cosmos DB 中的部分文件更新
適用於:NoSQL
Azure Cosmos DB 部分文件更新功能 (也稱為修補 API) 提供一個便利的方式來修改容器中的文件。 目前,若要更新文件,用戶端必須進行讀取、執行開放式同步控制檢查 (如有必要)、在本機更新文件,然後以整份文件取代 API 呼叫的方式透過網路進行傳送。
部分文件更新功能可大幅改善此體驗。 用戶端只能傳送文件中修改過的屬性/欄位,而不需要執行完整的文件取代作業。 此功能的主要優點包括:
- 提升開發人員生產力:提供易於使用的便利 API,以及有條件地更新文件的能力。
- 效能改進:避免用戶端額外的 CPU 週期,降低端對端延遲和網路頻寬。
- 多重區域寫入:透過在相同文件內離散路徑的部分更新,支援自動和透明的衝突解決方式。
注意
部分文件更新作業是以 JSON 修補檔 RFC 為基礎。 路徑中的屬性名稱必須分別將 ~
和 /
字元逸出為 ~0
和 ~1
。
以 JSON 文件為目標的範例:
{
"id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
"name": "R-410 Road Bicycle",
"price": 455.95,
"inventory": {
"quantity": 15
},
"used": false,
"categoryId": "road-bikes",
"tags": ["r-series"]
}
JSON 修補程式文件:
[
{ "op": "add", "path": "/color", "value": "silver" },
{ "op": "remove", "path": "/used" },
{ "op": "set", "path": "/price", "value": 355.45 }
{ "op": "incr", "path": "/inventory/quantity", "value": 10 },
{ "op": "add", "path": "/tags/-", "value": "featured-bikes" },
{ "op": "move", "from": "/color", "path": "/inventory/color" }
]
產生的 JSON 文件:
{
"id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
"name": "R-410 Road Bicycle",
"price": 355.45,
"inventory": {
"quantity": 25,
"color": "silver"
},
"categoryId": "road-bikes",
"tags": ["r-series", "featured-bikes"]
}
支援的作業
此表格摘要說明此功能支援的作業。
注意
目標路徑指的是 JSON 文件中的位置
作業類型 | 描述 |
---|---|
加入 | Add 會根據目標路徑,執行下列其中一項:• 如果目標路徑指定的元素不存在,則會加以新增。 • 如果目標路徑指定的元素已存在,則其值會遭到取代。 • 如果目標路徑是有效的陣列索引,將會在指定索引的陣列中插入新元素。 這會讓現有元素移位到新元素之後。 • 如果指定的索引等於陣列的長度,則會將元素附加至陣列。 您也可以使用 - 字元,而不是指定索引。 這也會讓元素附加到陣列。注意:指定大於陣列長度的索引將會產生錯誤。 |
設定 | 除了陣列資料類型之外,Set 作業與 Add 類似。 如果目標路徑是有效的陣列索引,則會更新該索引的現有元素。 |
Replace | Replace 作業類似於 Set ,但其會遵循嚴格的僅限取代語意。 如果目標路徑指定了不存在的元素或陣列,則會產生錯誤。 |
移除 | Remove 會根據目標路徑,執行下列其中一項:• 如果目標路徑指定了不存在的元素,則會產生錯誤。 • 如果目標路徑指定的元素已存在,則會將其移除。 • 如果目標路徑是陣列索引,則會將其刪除,且指定索引上方的任何元素都會往回移位一個位置。 注意:指定等於或大於陣列長度的索引將會產生錯誤。 |
[遞增] | 這個運算子會依指定的值遞增欄位。 其可以同時接受正值和負值。 如果欄位不存在,則會建立該欄位,並將其設定為指定的值。 |
移動 | 這個運算子會移除位於指定位置的值,並將其新增至目標位置。 作業物件必須包含「from」成員;這是包含 JSON 指標的字串,可參考目標文件中要移動值的位置。 「from」位置必須存在,才能讓作業成功。如果「path」位置建議不存在的物件,就會建立該物件,並將值設定為等於「from」位置的值 • 如果「path」位置建議已存在的物件,則會將「path」位置的值取代為「from」位置的值 •「Path」屬性不能是「from」JSON 位置的 JSON 子項目 |
支援的模式
部分文件更新功能支援下列作業模式。 請參閱開始使用文件以取得程式碼範例。
單一文件修補:您可以根據識別碼和分割區索引鍵來修補單一文件。 您可以在單一文件執行多個修補檔作業。 最大限制為 10 個作業。
多文件修補:相同分割區索引鍵內的多個文件可以作為交易的一部分進行修補。 只有在所有作業都以其描述的順序成功時,才會認可此項多文件交易。 如果任何作業失敗,則會復原整個交易。
有條件的更新:針對上述的模式,您也可以新增類似 SQL 的篩選述詞 (例如
from c where c.taskNum = 3
);因此如果未滿足述詞中指定的前置條件,作業就會失敗。您也可以使用支援之 SDK 的大量 API,在多份文件上執行一或多個修補作業。
相似與差異
現在就來比較支援模式之間相似和差異的部份。
新增與設定
除了 Array
以外的所有資料類型,Set
作業都與 Add
類似。 任何 (有效) 索引的 Add
作業,都會導致在指定的索引新增元素,而陣列中的任何現有元素都會移位到現有元素之後。 此行為與在指定索引處更新現有元素的 Set
作業相反。
新增與取代
Add
作業會新增屬性 (如果尚未存在) (包括 Array
資料類型)。 如果屬性不存在,Replace
作業就會失敗 (也適用於 Array
資料類型)。
設定與取代
Set
作業會新增尚不存在的屬性 (除非有 Array
)。 如果屬性不存在,Replace
作業就會失敗 (也適用於 Array
資料類型)。
注意
Replace
是很好的候選項目,使用者預期某些屬性一律存在,而且可讓您判斷提示/強制執行。
部分文件更新的 REST API 參考
Azure Cosmos DB REST API 可讓您以程式設計方式存取 Azure Cosmos DB 資源,以建立、查詢及刪除資料庫、文件集合和文件。 除了在集合中對 JSON 文件執行插入、取代、刪除、讀取、列舉和查詢作業之外,您還可以針對部分文件更新作業使用 PATCH
HTTP 方法。 如需詳細資訊,請參閱 Azure Cosmos DB REST API 參考。
例如,以下是使用部分文件更新的 set
作業所需要求的樣子。
PATCH https://querydemo.documents.azure.com/dbs/FamilyDatabase/colls/FamilyContainer/docs/Andersen.1 HTTP/1.1
x-ms-documentdb-partitionkey: ["Andersen"]
x-ms-date: Tue, 29 Mar 2016 02:28:29 GMT
Authorization: type%3dmaster%26ver%3d1.0%26sig%3d92WMAkQv0Zu35zpKZD%2bcGSH%2b2SXd8HGxHIvJgxhO6%2fs%3d
Content-Type:application/json_patch+json
Cache-Control: no-cache
User-Agent: Microsoft.Azure.DocumentDB/2.16.12
x-ms-version: 2015-12-16
Accept: application/json
Host: querydemo.documents.azure.com
Cookie: x-ms-session-token#0=602; x-ms-session-token=602
Content-Length: calculated when request is sent
Connection: keep-alive
{
"operations": [
{
"op": "set",
"path": "/Parents/0/FamilyName",
"value": "Bob"
}
]
}
文件等級與路徑等級衝突解決方式
如果 Azure Cosmos DB 帳戶設定了多個寫入區域,則衝突和衝突解決原則適用於文件等級,最後寫入為準 (LWW
) 是預設的衝突解決原則。 針對部分文件更新,跨多個區域的修補作業會偵測並解決在更細微路徑等級上的衝突。
您可透過範例更清楚了解衝突的解決方式。
假設您在 Azure Cosmos DB 中有下列文件:
{
"id": 1,
"name": "John Doe",
"email": "jdoe@contoso.com",
"phone": ["12345", "67890"],
"level": "gold"
}
不同用戶端會跨不同區域同時發出修補檔作業:
/level
屬性Set
為 platinum- 從
/phone
Remove
67890
由於修補檔要求是對文件內非衝突路徑所發出,因此會自動透明地 (而不是在文件等級以最後寫入為準的方式) 解決這些要求的衝突。
用戶端會在衝突解決之後看到下列文件:
{
"id": 1,
"name": "John Doe",
"email": "jdoe@contoso.com",
"phone": ["12345"],
"level": "platinum"
}
注意
如果同時在多個區域修補文件的相同屬性,則適用一般衝突解決原則。
變更摘要
Azure Cosmos DB 中的變更摘要會接聽容器是否有任何變更,然後將已變更的文件輸出。 使用變更摘要時,您會看到文件的所有更新,包括部分和完整文件更新。 您處理變更摘要的項目時,即使更新是由修補檔作業觸發,也會傳回完整文件。
如需 Azure Cosmos DB 中變更摘要的詳細資訊,請參閱 Azure Cosmos DB 中的變更摘要。