JavaScript 用 Azure Cosmos DB クライアント ライブラリ - バージョン 4.0.0

/Typescript

最新の npm バッジビルドの状態

Azure Cosmos DB はグローバル分散型のマルチモデル データベース サービスであり、ドキュメント、キー値、ワイドカラム、グラフのデータベースをサポートします。 このパッケージは、JavaScript/TypeScript アプリケーションが SQL API データベースと、それらが含む JSON ドキュメントと対話することを目的としています。

  • Cosmos DB データベースを作成し、その設定を変更する
  • JSON ドキュメントのコレクションを格納するためのコンテナーを作成および変更する
  • コンテナー内の項目 (JSON ドキュメント) を作成、読み取り、更新、削除する
  • SQL のような構文を使用してデータベース内のドキュメントに対してクエリを実行する

主要リンク:

作業の開始

前提条件

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 Portal でアカウントを作成することもできます

NodeJS

このパッケージは、NodeJS と共にプレインストールされる npm 経由で配布されます。 Node v10 以降を使用している必要があります。

CORS

ブラウザー用に開発する必要がある場合は、Cosmos DB アカウントのクロスオリジン リソース共有 (CORS) ルールを設定する必要があります。 リンクされたドキュメントの指示に従って、Cosmos DB の新しい CORS ルールを作成します。

このパッケージをインストールする

npm install @azure/cosmos

アカウントの資格情報を取得する

Cosmos DB アカウント エンドポイントキーが必要です。 これらは Azure Portal で見つけることができます。または、以下の Azure CLI スニペットを使用できます。 このスニペットは Bash シェル用にフォーマットされています。

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);
});

わかりやすくするために、keyendpoint をコードに直接含めましたが、dotenv などのプロジェクトを使用してソース管理にないファイルからこれらを読み込んだり、環境変数から読み込んだりする必要がある可能性があります

運用環境では、キーなどのシークレットを Azure Key Vault に格納する必要があります

主要な概念

CosmosClient を初期化したら、Cosmos DB でプライマリ リソースの種類を操作できます。

  • データベース: Cosmos DB アカウントに複数のデータベースを含めることができます。 データベースを作成する場合は、ドキュメントを操作するときに使用する API を指定します (SQL、MongoDB、Gremlin、Cassandra、または Azure Table)。 データベース オブジェクトを使用して、そのコンテナーを管理します。

  • コンテナー:コンテナーは、JSON ドキュメントのコレクションです。 コンテナー オブジェクトでメソッドを使用して、コンテナー内の項目を作成 (挿入)、読み取り、更新、および削除します。

  • Item:項目は、コンテナーに格納されている 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

パーティション キーが 1 つの値で構成されている場合は、リテラル値または配列として指定できます。

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 。 指定しない場合、SDK によって自動的に id が生成されます。

この例では、コンテナーに複数の項目を挿入します

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);
}

項目を読み取る

コンテナーから 1 つの項目を読み取るには、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);

階層パーティション キーが として定義されたコンテナーから 1 つの項目を読み取る方法 ["/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して、1 ページあたりに受信するアイテムの最大数を設定できます。

注: 値が指定されていない changeFeedStartFrom 場合、Changefeed は Now() からコンテナー全体に対してフェッチされます。

変更フィードには、次の 4 つの開始位置があります。

  • 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 では、操作中に発生する可能性があるさまざまな種類のエラーが生成されます。

  1. ErrorResponse は、操作の応答がエラー コード >=400 を返す場合にスローされます。
  2. TimeoutError は、タイムアウトが原因で Abort が内部的に呼び出された場合にスローされます。
  3. AbortError は、ユーザーがシグナルを渡した場合に、中止の原因となった場合にスローされます。
  4. RestError は、ネットワークの問題が原因で基になるシステム呼び出しが失敗した場合にスローされます。
  5. devDependencies によって生成されたエラー。 例: @azure/identity パッケージは をスロー CredentialUnavailableErrorする可能性があります。

、、、および 型ErrorResponseTimeoutErrorAbortErrorのエラーを処理する例をRestError次に示します。

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 状態コードに対応しています。

Azure Cosmos DB の 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 をサポートするように設計されています。 Internet Explorer や Node 6 などの以前の JavaScript ランタイムのサポートが必要な場合は、ビルド プロセスの一環として SDK コードをトランスパイルする必要があります。

再試行による一時的なエラーを処理する

Computer DB の操作中に、このサービスによって適用されたレート制限によって一時的な障害が発生したり、ネットワークの停止など、他の一時的な問題が発生したりする可能性があります。 これらの種類の障害の処理については、クラウド設計パターン ガイドの「再試行パターン」および「サーキット ブレーカー パターン」を参照してください。

ログの記録

ログの記録を有効にすると、エラーに関する有用な情報を明らかにするのに役立つ場合があります。 HTTP 要求と応答のログを表示するには、環境変数 AZURE_LOG_LEVELinfo に設定します。 または、 で を呼び出 setLogLevel すことで、実行時にログ記録を @azure/logger有効にすることもできます。 を使用 AZURE_LOG_LEVEL している間は、ログ ライブラリが初期化される前に必ず設定してください。 ライブラリを dotenv 使用する場合は、ライブラリをログ記録する前にそのようなライブラリが初期化されていることを確認する場合は、コマンド ラインを介して渡すのが理想的です。

const { setLogLevel } = require("@azure/logger");
setLogLevel("info");

ログを有効にする方法の詳細については、@azure/logger パッケージに関するドキュメントを参照してください。

診断

Cosmos Diagnostics 機能は、すべてのクライアント操作に関する強化された分析情報を提供します。 CosmosDiagnostics オブジェクトは、すべてのクライアント操作の応答に追加されます。 例を以下に示します。

  • ポイント検索操作の応答 - item.read()、、 container.create()database.delete()
  • クエリ操作の応答 -queryIterator.fetchAll(),
  • 一括操作とバッチ操作 -item.batch().
  • Error/Exception 応答オブジェクト。

CosmosDiagnostics オブジェクトは、すべてのクライアント操作の応答に追加されます。 Cosmos Diagnostic には、3 つのレベル、情報、デバッグ、デバッグセーフがあります。 実稼働システム用の情報のみであり、デバッグとデバッグの安全でない情報は、開発およびデバッグ中に使用されることを意図しています。これは、大幅に高いリソースを消費するためです。 Cosmos 診断レベルは 2 つの方法で設定できます

  • プログラム
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • 環境変数の使用。 (環境変数によって設定された診断レベルは、クライアント オプションを使用して設定するよりも優先度が高くなります)。
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

Cosmos Diagnostic には 3 つのメンバーがあります

  • ClientSideRequestStatistics の種類: メタデータの参照、再試行、接続されたエンドポイント、ペイロードのサイズや期間などの要求と応答の統計情報など、診断の詳細を集計します。 (常に収集され、運用システムで使用できます)。

  • DiagnosticNode: 詳細な診断情報をキャプチャするツリーのような構造です。 ブラウザーに存在する har 記録に似ています。 この機能は既定で無効になっており、非運用環境のデバッグのみを目的としています。 (診断レベルのデバッグと debug-unsafe で収集)

  • ClientConfig: クライアントの初期化中にクライアントの構成設定に関連する重要な情報をキャプチャします。 (診断レベルのデバッグと debug-unsafe で収集)

このレベルでは要求と応答のペイロードをキャプチャし、ログにdebug-unsafe記録することを選択した場合 (既定ではレベルでログに記録@azure/loggerされるため)、運用環境ではverbose診断レベルCosmosDiagnosticsを に設定しないでください。 これらのペイロードは、ログ シンクにキャプチャされる場合があります。

診断の使用

  • 以降 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することもできます。診断は常に レベルで verbose を使用して@azure/loggerログに記録されます。 したがって、診断レベルを または debug-unsafe に設定し、@azure/loggerlevel を debugverbosediagnostics設定すると、ログに記録されます。

次のステップ

その他のサンプル コード

いくつかのサンプルは、SDK の GitHub リポジトリで入手できます。 これらのサンプルでは、Computer DB の操作中によく発生する追加のシナリオのコード例が示されています。

  • データベース操作
  • コンテナー操作
  • 項目操作
  • インデックス作成の構成
  • コンテナー変更フィードの読み取り
  • ストアド プロシージャ
  • データベースまたはコンテナーのスループット設定の変更
  • 複数リージョンの書き込み操作

制限事項

現在、以下の機能は サポートされていません。 代替オプションについては、以下の「回避策」セクションをチェック。

データ プレーンの制限事項:

  • DISTINCT サブクエリからの COUNT を使用したクエリ
  • TCP モードへの直接アクセス
  • 並べ替え、カウント、個別など、パーティション間のクエリを集計しても、継続トークンはサポートされません。 SELECT * FROM などのストリーミング可能なクエリ WHERE では、継続トークンがサポートされます。 継続トークンを使用せずにストリーミング不可能なクエリを実行する場合は、「回避策」セクションを参照してください。
  • 変更フィード: プロセッサ
  • 変更フィード: 複数のパーティション キー値を読み取ります
  • 変更フィード プル モデルのすべてのバージョンと削除モード #27058
  • 部分階層パーティション キーの変更フィード プル モデルのサポート #27059
  • 混合型のクロスパーティション ORDER BY
  • コントロール プレーンの制限事項:

    • CollectionSizeUsage、DatabaseUsage、DocumentUsage のメトリックを取得する
    • 地理空間インデックスを作成する
    • 自動スケーリングスループットを更新する

    対処方法

    クロス パーティション クエリの継続トークン

    Side car パターンを使用すると、継続トークンのサポートを使用してクロス パーティション クエリを実現できます。 このパターンは、種類が異なるコンポーネントとテクノロジでアプリケーションを構成することも可能にします。

    stremable 以外のクロスパーティション クエリの実行

    継続トークンを使用せずにストリーミング不可能なクエリを実行するには、必要なクエリの仕様とオプションを使用してクエリ反復子を作成できます。 次のサンプル コードは、クエリ反復子を使用して、継続トークンを必要とせずにすべての結果をフェッチする方法を示しています。

    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 PortalAzure Cosmos DB リソース プロバイダー REST APIAzure CLIまたは PowerShell を使用できます。

    その他のドキュメント

    Cosmos DB サービスに関するさらに詳細なドキュメントについては、docs.microsoft.com にある Azure Cosmos DB のドキュメントを参照してください。

    共同作成

    このライブラリに投稿する場合、コードをビルドしてテストする方法の詳細については、投稿ガイドを参照してください。

    インプレッション数