適用于 JavaScript 的 Azure Cosmos DB 用戶端程式庫 - 4.0.0 版
/TypeScript
Azure Cosmos DB 是全域散發、多模型資料庫服務,支援文件、索引鍵/值組、寬列資料行及圖形資料庫。 此套件適用于 JavaScript/TypeScript 應用程式與 SQL API 資料庫與其包含的 JSON 檔互動:
- 建立 Cosmos DB 資料庫並修改相關設定
- 建立和修改容器以儲存 JSON 文件的集合
- 建立、讀取、更新和刪除容器中的項目 (JSON 文件)
- 使用與 SQL 相似的語法查詢資料庫的文件
重要連結:
開始使用
Prerequisites
Azure 訂用帳戶與 Cosmos DB SQL API 帳戶
您必須擁有 Azure 訂用帳戶和 Cosmos DB 帳戶 (SQL API) 才能使用此套件。
如果您需要 Cosmos DB SQL API 帳戶,可以使用 Azure Cloud Shell 並藉由此 Azure CLI 命令建立帳戶:
az cosmosdb create --resource-group <resource-group-name> --name <cosmos-database-account-name>
或者您也可以在 Azure 入口網站中建立帳戶
NodeJS
此套件會透過預先安裝 NodeJS 的 npm 散發。 您應該使用 Node v10 或更新版本。
CORS
如果您需要針對瀏覽器進行開發,您必須為 Cosmos DB 帳戶設定跨原始來源資源共用 (CORS) 規則。 請遵循連結文件中的指示,為您的 Cosmos DB 建立新的 CORS 規則。
安裝此套件
npm install @azure/cosmos
取得帳戶認證
您需要 Cosmos DB 帳戶端點和金鑰。 您可以在 Azure 入口網站中找到這些資訊,或使用下方的 Azure CLI 程式碼片段。 此程式碼片段會針對 Bash Shell 加以格式化。
az cosmosdb show --resource-group <your-resource-group> --name <your-account-name> --query documentEndpoint --output tsv
az cosmosdb keys list --resource-group <your-resource-group> --name <your-account-name> --query primaryMasterKey --output tsv
建立 CosmosClient
的執行個體
與 Cosmos DB 的互動會從 CosmosClient 類別的執行個體開始
const { CosmosClient } = require("@azure/cosmos");
const endpoint = "https://your-account.documents.azure.com";
const key = "<database account masterkey>";
const client = new CosmosClient({ endpoint, key });
async function main() {
// The rest of the README samples are designed to be pasted into this function body
}
main().catch((error) => {
console.error(error);
});
為了簡單起見,我們已將 key
和 endpoint
直接包含在程式碼中,但您可能會想使用 dotenv 等專案,從並非位於原始檔控制的文件中載入這些程式碼,或是從環境變數載入
在實際執行環境中,金鑰等秘密應該儲存在 Azure Key Vault
重要概念
當您將 CosmosClient 初始化之後,便能與 Cosmos DB 中的主要資源類型互動:
資料庫:一個 Cosmos DB 帳戶可以包含多個資料庫。 在建立資料庫時,您可以指定在與資料庫內文件互動時想使用的 API:SQL、MongoDB、Gremlin、Cassandra 或 Azure Table。 使用資料庫物件來管理容器。
項目:項目是儲存在容器中的 JSON 文件。 每個項目都必須包含一個
id
金鑰,此金鑰值可唯一識別容器內的項目。 如果您不提供id
,SDK 就會自動產生一個。
如需這些資源的詳細資訊,請參閱使用 Azure Cosmos 資料庫、容器和項目。
範例
下列各節提供數個程式碼片段,內容涵蓋一些最常見的 Cosmos DB 工作,包括:
建立資料庫
驗證 CosmosClient 之後,您便能使用帳戶中的任何資源。 下列程式碼片段會建立 NOSQL API 資料庫。
const { database } = await client.databases.createIfNotExists({ id: "Test Database" });
console.log(database.id);
建立容器
此範例會建立使用預設設定的容器
const { container } = await database.containers.createIfNotExists({ id: "Test Database" });
console.log(container.id);
使用分割區索引鍵
此範例顯示支援的各種分割區索引鍵類型。
await container.item("id", "1").read(); // string type
await container.item("id", 2).read(); // number type
await container.item("id", true).read(); // boolean type
await container.item("id", {}).read(); // None type
await container.item("id", undefined).read(); // None type
await container.item("id", null).read(); // null type
如果資料分割索引鍵是由單一值所組成,則可以常值或陣列的形式提供。
await container.item("id", "1").read();
await container.item("id", ["1"]).read();
如果資料分割索引鍵包含一個以上的值,則應該以陣列的形式提供。
await container.item("id", ["a", "b"]).read();
await container.item("id", ["a", 2]).read();
await container.item("id", [{}, {}]).read();
await container.item("id", ["a", {}]).read();
await container.item("id", [2, null]).read();
插入項目
若要將項目插入容器中,請將包含資料的物件傳遞至 Items.upsert。 Azure Cosmos DB 服務需要每個專案都有金鑰 id
。 如果您不提供 id
,SDK 就會自動產生一個。
此範例會將數個項目插入容器中
const cities = [
{ id: "1", name: "Olympia", state: "WA", isCapitol: true },
{ id: "2", name: "Redmond", state: "WA", isCapitol: false },
{ id: "3", name: "Chicago", state: "IL", isCapitol: false }
];
for (const city of cities) {
await container.items.create(city);
}
讀取項目
若要從容器讀取單一項目,請使用 Item.read。 相較於使用 SQL,使用 id
查詢是成本較低的作業。
await container.item("1", "1").read();
容器上具有階層式分割區索引鍵的 CRUD
使用階層式分割區索引鍵建立容器
const containerDefinition = {
id: "Test Database",
partitionKey: {
paths: ["/name", "/address/zip"],
version: PartitionKeyDefinitionVersion.V2,
kind: PartitionKeyKind.MultiHash,
},
}
const { container } = await database.containers.createIfNotExists(containerDefinition);
console.log(container.id);
插入定義為 的階層式分割區索引鍵的專案 - ["/name", "/address/zip"]
const item = {
id: 1,
name: 'foo',
address: {
zip: 100
},
active: true
}
await container.items.create(item);
若要從定義為 的階層式分割區索引鍵的容器讀取單一專案 - ["/name", "/address/zip"],
await container.item("1", ["foo", 100]).read();
使用定義為 的階層式分割區索引鍵來查詢具有階層式分割區索引鍵的專案- ["/name", "/address/zip"],
const { resources } = await container.items
.query("SELECT * from c WHERE c.active = true", {
partitionKey: ["foo", 100],
})
.fetchAll();
for (const item of resources) {
console.log(`${item.name}, ${item.address.zip} `);
}
刪除項目
若要從容器中刪除項目,請使用 Item.delete。
// Delete the first item returned by the query above
await container.item("1").delete();
查詢資料庫
Cosmos DB SQL API 資料庫支援使用與 SQL 相似的語法,以 Items.query 查詢容器中的項目:
const { resources } = await container.items
.query("SELECT * from c WHERE c.isCapitol = true")
.fetchAll();
for (const city of resources) {
console.log(`${city.name}, ${city.state} is a capitol `);
}
將包含參數及相關值的物件傳遞至 Items.query,以執行參數化查詢:
const { resources } = await container.items
.query({
query: "SELECT * from c WHERE c.isCapitol = @isCapitol",
parameters: [{ name: "@isCapitol", value: true }]
})
.fetchAll();
for (const city of resources) {
console.log(`${city.name}, ${city.state} is a capitol `);
}
如需使用 SQL API 查詢 Cosmos DB 資料庫的詳細資訊,請參閱使用 SQL 查詢進行 Azure Cosmos DB 資料查詢。
變更摘要提取模型
您可以擷取分割區索引鍵、摘要範圍或整個容器的變更摘要。
若要處理變更摘要,請建立 的 ChangeFeedPullModelIterator
實例。 當您一開始建立 ChangeFeedPullModelIterator
時,必須在 內 ChangeFeedIteratorOptions
指定必要的 changeFeedStartFrom
值,其中包含讀取變更的起始位置,以及資源 (分割區索引鍵或要擷取變更的 FeedRange) 。 您可以選擇性地在 中 ChangeFeedIteratorOptions
用來 maxItemCount
設定每頁收到的專案數目上限。
注意:如果未指定任何 changeFeedStartFrom
值,則會從 Now () 擷取整個容器的變更摘要。
變更摘要有四個起始位置:
Beginning
// Signals the iterator to read changefeed from the beginning of time.
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Beginning();
}
const iterator = container.getChangeFeedIterator(options);
Time
// Signals the iterator to read changefeed from a particular point of time.
const time = new Date("2023/09/11") // some sample date
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Time(time);
}
Now
// Signals the iterator to read changefeed from this moment onward.
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Now();
}
Continuation
// Signals the iterator to read changefeed from a saved point.
const continuationToken = "some continuation token recieved from previous request";
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Continuation(continuationToken);
}
以下是擷取分割區索引鍵變更摘要的範例
const partitionKey = "some-partition-Key-value";
const options = {
changeFeedStartFrom: ChangeFeedStartFrom.Beginning(partitionKey),
};
const iterator = container.items.getChangeFeedIterator(options);
while (iterator.hasMoreResults) {
const response = await iterator.readNext();
// process this response
}
因為變更摘要實際上是包含所有未來寫入和更新的無限專案清單,所以 hasMoreResults
的值一律 true
為 。 當您嘗試讀取變更摘要且沒有可用的新變更時,您會收到狀態為的 NotModified
回應。
如需更詳細的使用方針和變更摘要範例,請參閱 這裡。
錯誤處理
SDK 會產生作業期間可能發生的各種錯誤類型。
ErrorResponse
如果作業的回應傳回錯誤碼 > =400,則會擲回 。TimeoutError
如果因逾時在內部呼叫 Abort,則會擲回 。AbortError
如果任何使用者通過的訊號造成中止,則會擲回 。RestError
如果基礎系統呼叫因網路問題而失敗,則會擲回 。- 任何 devDependencies 所產生的錯誤。 例如
@azure/identity
封裝可能會擲回CredentialUnavailableError
。
以下是處理 、 TimeoutError
、 AbortError
和 RestError
類型 ErrorResponse
錯誤的範例。
try {
// some code
} catch (err) {
if (err instanceof ErrorResponse) {
// some specific error handling.
} else if (err instanceof RestError) {
// some specific error handling.
}
// handle other type of errors in similar way.
else {
// for any other error.
}
}
請務必正確處理這些錯誤,以確保您的應用程式可以從任何失敗正常復原,並繼續如預期般運作。 如需這些錯誤及其可能解決方案的詳細資訊,請參閱 這裡。
疑難排解
一般
當您與服務所傳回的 Cosmos DB 錯誤互動時,其會對應至 REST API 要求所傳回的相同 HTTP 狀態碼:
衝突
例如,如果您嘗試使用已經在 Cosmos DB 資料庫中使用的 id
來建立項目,則會傳回 409
錯誤,指出衝突所在。 下列程式碼片段會藉由攔截例外狀況並顯示錯誤的其他相關資訊,來適當地處理錯誤。
try {
await containers.items.create({ id: "existing-item-id" });
} catch (error) {
if (error.code === 409) {
console.log("There was a conflict with an existing item");
}
}
轉譯
Azure SDK 是專為支援 ES5 JavaScript 語法和 LTS 版本的 Node.js 而設計。 如果您需要獲得舊版 JavaScript 執行階段的支援 (例如 Internet Explorer 或 Node 6),您必須在組建程序中轉譯 SDK 程式碼。
透過重試來處理暫時性錯誤
在使用 Cosmos DB 時,您可能會遇到由於服務強制執行速率限制或其他暫時性問題 (例如網路中斷) 而導致的暫時性失敗。 如需如何處理這些失敗類型的相關資訊,請參閱《雲端設計模式》指南中的重試模式,以及相關的斷路器模式。
記錄
啟用記錄有助於找出失敗的相關實用資訊。 若要查看 HTTP 的要求和回應記錄,請將 AZURE_LOG_LEVEL
環境變數設定為 info
。 或者,您可以在 執行時間呼叫 setLogLevel
來 @azure/logger
啟用記錄。 使用 AZURE_LOG_LEVEL
時,請務必在記錄程式庫初始化之前加以設定。
最好是透過命令列傳遞它,如果使用之類的 dotenv
程式庫,請務必在記錄程式庫之前先初始化這類程式庫。
const { setLogLevel } = require("@azure/logger");
setLogLevel("info");
如需如何啟用記錄的詳細指示,可參閱 @azure/logger 套件文件。
診斷
Cosmos 診斷功能可增強您所有用戶端作業的深入解析。 新增 CosmosDiagnostics 物件以回應所有用戶端作業。 例如
- 點查閱作業回應 -
item.read()
、 、container.create()
database.delete()
- 查詢作業回應 -
queryIterator.fetchAll()
, - 大量和 Batch 作業 -
item.batch()
. - 錯誤/例外狀況回應物件。
新增 CosmosDiagnostics 物件以回應所有用戶端作業。 有 3 個 Cosmos 診斷層級、資訊、偵錯和偵錯不安全。 其中只有資訊適用于生產系統,且偵錯和偵錯不安全的用途是在開發和偵錯期間使用,因為它們耗用了較高的資源。 Cosmos 診斷層級可以透過 2 種方式設定
- 程式設計方式
const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
- 使用環境變數。 (環境變數所設定的診斷層級優先順序高於透過用戶端選項進行設定。)
export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"
Cosmos 診斷有三個成員
ClientSideRequestStatistics 類型:包含匯總診斷詳細資料,包括中繼資料查閱、重試、連絡的端點,以及承載大小和持續時間等要求和回應統計資料。 一律會收集 (,可用於生產系統。)
DiagnosticNode:這是擷取詳細診斷資訊的類似樹狀結構。 類似于
har
在瀏覽器中錄製。 此功能預設為停用,且僅供偵錯非生產環境。 在診斷層級偵錯和偵錯不安全) 收集 (ClientConfig:擷取用戶端初始化期間與用戶端組態設定相關的基本資訊。 在診斷層級偵錯和偵錯不安全) 收集 (
請務必絕對不要在生產環境中將診斷層級設定為 debug-unsafe
,因為此層級 CosmosDiagnostics
會擷取要求和回應承載,而且如果您選擇將它 @azure/logger 記錄 (預設會記錄在 verbose
層級) 。 這些承載可能會在記錄接收中擷取。
取用診斷
- 由於
diagnostics
會新增至所有 Response 物件。 您可以依程式設計方式存取CosmosDiagnostic
,如下所示。
// For point look up operations
const { container, diagnostics: containerCreateDiagnostic } =
await database.containers.createIfNotExists({
id: containerId,
partitionKey: {
paths: ["/key1"],
},
});
// For Batch operations
const operations: OperationInput[] = [
{
operationType: BulkOperationType.Create,
resourceBody: { id: 'A', key: "A", school: "high" },
},
];
const response = await container.items.batch(operations, "A");
// For query operations
const queryIterator = container.items.query("select * from c");
const { resources, diagnostics } = await queryIterator.fetchAll();
// While error handling
try {
// Some operation that might fail
} catch (err) {
const diagnostics = err.diagnostics
}
- 您也可以使用
@azure/logger
來記錄diagnostics
,診斷一律會在層級記錄。@azure/logger
verbose
因此,如果您將 [診斷層級] 設定為debug
或debug-unsafe
並將@azure/logger
層級設定為verbose
,diagnostics
則會記錄 。
下一步
更多的程式碼範例
SDK 的 GitHub 存放庫中有數個範例可供您參考。 這些範例會提供在使用 Cosmos DB 時所經常遇到其他案例的程式碼範例:
- 資料庫作業
- 容器作業
- 項目操作
- 設定索引
- 讀取容器變更摘要
- 預存程序
- 變更資料庫/容器輸送量設定
- 多重區域寫入作業
限制
目前 不支援下列功能。 如需替代選項,請查看下方 的因應措施 一節。
資料平面限制:
- 從 DISTINCT 子查詢使用 COUNT 的查詢
- 直接 TCP 模式存取
- 匯總跨分割區查詢,例如排序、計數和相異,不支援接續權杖。 可串流查詢,例如 SELECT * FROM WHERE ,支援接續權杖。 請參閱一節,以瞭解在沒有接續權杖的情況下執行不可串流查詢。
- 變更摘要:處理器
- 變更摘要:讀取多個分割區索引鍵值
- 變更摘要提取模型所有版本和刪除模式 #27058
- 變更部分階層式分割區索引鍵的摘要提取模型支援 #27059
- 混合類型的跨分割區 ORDER BY
- 取得 CollectionSizeUsage、DatabaseUsage 和 DocumentUsage 計量
- 建立地理空間索引
- 更新自動調整輸送量
控制平面限制:
因應措施
跨分割區查詢的接續權杖
您可以使用 側車模式,透過接續權杖支援來達成跨分割區查詢。 此模式也可讓應用程式由異質元件和技術組成。
執行不可建構的跨分割區查詢
若要在不使用接續權杖的情況下執行不可串流查詢,您可以使用必要的查詢規格和選項來建立查詢反覆運算器。 下列範例程式碼示範如何使用查詢反覆運算器來擷取所有結果,而不需要接續權杖:
const querySpec = {
query: "SELECT * FROM c WHERE c.status = @status",
parameters: [{ name: "@status", value: "active" }],
};
const queryOptions = {
maxItemCount: 10, // maximum number of items to return per page
enableCrossPartitionQuery: true,
};
const querIterator = await container.items.query(querySpec, queryOptions);
while (querIterator.hasMoreResults()) {
const { resources: result } = await querIterator.fetchNext();
//Do something with result
}
此方法也可用於可串流查詢。
控制平面作業
一般而言,您可以針對控制平面不支援的限制,使用 Azure 入口網站、 Azure Cosmos DB 資源提供者 REST API、 Azure CLI 或 PowerShell 。
其他文件
如需 Cosmos DB 服務的更多詳細文件,請參閱 docs.microsoft.com 上的 Azure Cosmos DB 文件。
實用連結
- 歡迎使用 Azure Cosmos DB
- 快速入門
- 教學課程
- 範例
- Azure Cosmos DB 服務的資源模型簡介
- Azure Cosmos DB 服務的 SQL API 簡介
- 資料分割
- API 文件
參與
如果您希望向此程式庫投稿,請參閱投稿指南,深入瞭解如何組建與測試程式碼。