次の方法で共有


Azure AI 検索でクエリを実行するために Azure Cosmos DB for NoSQL からデータのインデックスを付ける

この記事では、インデクサーを構成する方法について説明します。これにより、Azure Cosmos DB for NoSQL からコンテンツがインポートされて、Azure AI Search で検索できるようになります。

この記事では、Cosmos DB に固有の情報を使用して、インデクサーの作成に関する記事を補足しています。 Azure portal と REST API を使用して、すべてのインデクサーに共通する 3 部構成のワークフロー (データ ソースの作成、インデックスの作成、インデクサーの作成) を示します。 データ抽出は、インデクサーの作成要求を送信したときに発生します。

用語が混乱を招く可能性があるため、Azure Cosmos DB のインデックス作成Azure AI Search のインデックス作成は異なる操作であることに注意してください。 Azure AI Search のインデックス作成では、検索インデックスが作成され、検索サービスに読み込まれます。

前提条件

この記事の例を実行するには、Azure portal または REST クライアントが必要です。 Azure portal を使う場合は、すべてのパブリック ネットワークへのアクセスが有効になっていることを確認してください。 Cosmos DB インデクサーを作成するその他の方法としては、Azure SDK があります。

サンプル データで試す

次の手順を使って、テスト目的で Cosmos DB にコンテナーとデータベースを作成します。

  1. GitHub から HotelsData_toCosmosDB.JSON をダウンロードして、サンプルであるホテルのデータ セットのサブセットを含むコンテナーを Cosmos DB に作成します。

  2. Azure portal にサインインし、Cosmos DB 上にアカウント、データベース、コンテナーを作成します。

  3. Cosmos DB で、新しいコンテナーのデータ エクスプローラーを選択し、次の値を指定します。

    プロパティ
    データベース 新規作成
    データベース ID hotelsdb
    コンテナー間でスループットを共有する 選択しません
    コンテナー ID ホテル
    [パーティション キー] /HotelId
    コンテナーのスループット (自動スケーリング) Autoscale
    コンテナーの最大 RU/秒 1000
  4. データ エクスプローラーで、hotelsdb と *hotels" を展開し、[項目] を選択します。

  5. [項目のアップロード] を選択し、GitHub からダウンロードしたファイル HotelsData_toCosmosDB.JSON を選択します。

  6. [項目] を右クリックし、[新しい SQL クエリ] を選択します。 既定のクエリは SELECT * FROM c です。

  7. [クエリの実行] を選択してクエリを実行し、結果を確認します。 ホテルのドキュメントが 50 個あるはずです。

コンテナーを作成できたので、Azure portal、REST クライアント、または Azure SDK を使ってデータのインデックスを作成できます。

Description フィールドには最も詳細な内容が含まれています。 このフィールドを、フルテキスト検索とオプションのベクトル クエリの対象にする必要があります。

Azure portal を使用する

データ インポート ウィザードまたはデータのインポートとベクトル化ウィザードのいずれかを使用して、SQL データベース テーブルまたはビューのインデックス作成を自動化できます。 データ ソースの構成は、どちらのウィザードも似ています。

  1. ウィザードを開始します。

  2. [データへの接続] で、データ ソースの種類に Azure Cosmos DB または "NoSQL アカウント" を選択するか、選択されていることを確認します。

    データ ソース名は、Azure AI 検索のデータ ソース接続オブジェクトを参照します。 ベクトル ウィザードを使う場合、データ ソース名は、ウィザード ワークフローの最後に指定したカスタム プレフィックスを使って自動生成されます。

  3. データベース名とコレクションを指定します。 クエリは省略可能です。 階層データがあり、特定のスライスをインポートしたい場合に便利です。

  4. マネージド ID または組み込みの API キーのいずれかの認証方法を指定します。 マネージド ID 接続を指定しない場合、Azure portal ではキーが使用されます。

    マネージド ID を使用するように Azure AI 検索を構成し、ID に対して Cosmos DB アカウント閲覧者Cosmos DB 組み込みデータ リーダーのアクセス許可を付与するロールの割り当てを Cosmos DB に作成した場合、インデクサーは Microsoft Entra ID とロールを使って Cosmos DB に接続できます。

  5. データのインポートとベクトル化ウィザードでは、変更と削除の追跡に関するオプションを指定できます。

    変更の検出は、_ts フィールド (タイムスタンプ) を使って既定でサポートされます。 「サンプル データで試す」で説明されている方法を使ってコンテンツをアップロードすると、コレクションは _ts フィールドと共に作成されます。

    削除の検出では、論理的な削除のフラグとして使用できる既存の最上位フィールドがコレクション内に存在している必要があります。 これは、ブール値フィールドにする必要があります (IsDeleted という名前を付けることができます)。 論理的に削除された値として true を指定します。 検索インデックスに、取得可能でフィルター可能に設定されている IsDeleted という対応する検索フィールドを追加します。

  6. 残りの手順に進み、ウィザードを完了します。

REST API を使用する

このセクションでは、データ ソース、インデックス、インデクサーを作成する REST API 呼び出しを示します。

データ ソースを定義する

データ ソース定義では、インデックスを付けるデータ、資格情報、データの変更を識別するためのポリシーを指定します。 データ ソースは、複数のインデクサーで使用できる独立したリソースです。

  1. データ ソースを作成または更新してその定義を設定します。

    POST https://[service name].search.windows.net/datasources?api-version=2024-07-01
    Content-Type: application/json
    api-key: [Search service admin key]
    {
        "name": "[my-cosmosdb-ds]",
        "type": "cosmosdb",
        "credentials": {
          "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.com;AccountKey=[cosmos-account-key];Database=[cosmos-database-name]"
        },
        "container": {
          "name": "[my-cosmos-db-collection]",
          "query": null
        },
        "dataChangeDetectionPolicy": {
          "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
        "  highWaterMarkColumnName": "_ts"
        },
        "dataDeletionDetectionPolicy": null,
        "encryptionKey": null,
        "identity": null
    }
    
  2. "type" を "cosmosdb" に指定します (必須)。 古い Search API バージョン 2017-11-11 を使用している場合、"type" の構文は "documentdb" です。 それ以外 (2019-05-06 以降) の場合は、"cosmosdb" を使用します。

  3. "credentials" を接続文字列に設定します。 続く部分は、サポートされている形式を記述します。

  4. "container" をコレクションに設定します。 "name" プロパティは必須です。これによって、インデックスが作成されるデータベース コレクションの ID を指定します。 "query" プロパティは省略可能です。 これは、任意の JSON ドキュメントをフラット化して、Azure AI Search でインデックスを作成できるフラット スキーマにするために使用します。

  5. データが変化しやすいので、以降の実行で新規および更新された項目だけをインデクサーで取得する場合は、"dataChangeDetectionPolicy" を設定します。

  6. ソース項目が削除されたら場合に検索インデックスから検索ドキュメントを削除する場合は、"dataDeletionDetectionPolicy" を設定します。

サポートされている資格情報と接続文字列

インデクサーは、次の接続を使用してコレクションに接続できます。

エンドポイント URL にポート番号は含めないでください。 ポート番号を含めると、接続は失敗します。

フル アクセス接続文字列
{ "connectionString" : "AccountEndpoint=https://<Cosmos DB account name>.documents.azure.com;AccountKey=<Cosmos DB auth key>;Database=<Cosmos DB database id>" }`
Azure portal の Azure Cosmos DB アカウント ページから接続文字列を取得するには、左側のナビゲーション ウィンドウの [キー] を選びます。 キーだけではなく、完全な接続文字列を選択してください。
(最新のアプローチ) NoSQL アカウントのマネージド ID 接続文字列
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)/(IdentityAuthType=AccessToken)" }
この接続文字列は、Azure Cosmos DB for NoSQL アカウントでのみサポートされており、Cosmos DB からデータにアクセスしようとしたときに、検索サービスがアカウント キー (バックグラウンドでも) を使用しないようにします。 これは、NoSQL アカウントでアカウント キーが無効になっている場合でも機能するため推奨されます。 詳細については、マネージド ID を使用した Azure Cosmos DB データベースへのインデクサー接続の設定に関するページを参照してください
(従来のアプローチ) マネージド ID 接続文字列
{ "connectionString" : "ResourceId=/subscriptions/<your subscription ID>/resourceGroups/<your resource group name>/providers/Microsoft.DocumentDB/databaseAccounts/<your cosmos db account name>/;(ApiKind=[api-kind];)/(IdentityAuthType=AccountKey)" }
この接続文字列では、アカウント キーを直接指定する必要はありませんが、検索サービスではマネージド ID を利用してバックグラウンドでアカウント キーをフェッチします。 これはすべての Cosmos DB アカウントの種類でサポートされていますが、NoSQL アカウントの種類では推奨されません。 Cosmos DB アカウントのアカウント キーが無効になっている場合、このような接続文字列は機能しません。 IdentityAuthType プロパティが省略されている場合、検索サービスでは引き続き既定でアカウント キーをバックグラウンドでフェッチします。 SQL API をターゲットとする接続の場合は、接続文字列から ApiKind を省略できます。 ApiKindIdentityAuthType の詳細については、マネージド ID を使用した Azure Cosmos DB データベースへのインデクサー接続の設定に関するページを参照してください

インデックス作成するデータの処理にクエリを活用する

"container" の下にある "query" プロパティで、SQL クエリを指定して、ネストされたプロパティや配列のフラット化、JSON プロパティのプロジェクション、インデックスを作成するデータのフィルター処理を行うことができます。

ドキュメントのサンプル:

    {
        "userId": 10001,
        "contact": {
            "firstName": "andy",
            "lastName": "hoh"
        },
        "company": "microsoft",
        "tags": ["azure", "cosmosdb", "search"]
    }

フィルター処理クエリ:

SELECT * FROM c WHERE c.company = "microsoft" and c._ts >= @HighWaterMark ORDER BY c._ts

平坦化クエリ:

SELECT c.id, c.userId, c.contact.firstName, c.contact.lastName, c.company, c._ts FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

プロジェクション クエリ:

SELECT VALUE { "id":c.id, "Name":c.contact.firstName, "Company":c.company, "_ts":c._ts } FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

配列を平坦化するクエリ:

SELECT c.id, c.userId, tag, c._ts FROM c JOIN tag IN c.tags WHERE c._ts >= @HighWaterMark ORDER BY c._ts

サポートされていないクエリ (DISTINCT と GROUP BY)

DISTINCT キーワードまたは GROUP BY 句を使用するクエリはサポートされていません。 Azure AI Search は、クエリの結果を完全に列挙するために、SQL クエリの改ページに依存します。 DISTINCT キーワードと GROUP BY 句はどちらも、結果の改ページに使用される継続トークンに対応していません。

サポートされていないクエリの例を以下に示します。

SELECT DISTINCT c.id, c.userId, c._ts FROM c WHERE c._ts >= @HighWaterMark ORDER BY c._ts

SELECT DISTINCT VALUE c.name FROM c ORDER BY c.name

SELECT TOP 4 COUNT(1) AS foodGroupCount, f.foodGroup FROM Food f GROUP BY f.foodGroup

Azure Cosmos DB では、ORDER BY 句を使用した DISTINCT キーワードによる SQL クエリの改ページをサポートするための回避策がありますが、これは Azure AI Search には対応していません。 クエリでは 1 つの JSON 値が返されるのに対し、Azure AI Search では JSON オブジェクトを受け取る必要があります。

-- The following query returns a single JSON value and isn't supported by Azure AI Search
SELECT DISTINCT VALUE c.name FROM c ORDER BY c.name

インデックスに検索フィールドを追加する

検索インデックスに、ソース JSON ドキュメントまたはカスタム クエリ プロジェクションの出力を受け入れるフィールドを追加します。 検索インデックス スキーマがソース データに対応していることを確認してください。 Azure Cosmos DB 内のコンテンツの場合、検索インデックス スキーマは、データ ソース内の Azure Cosmos DB の項目に対応している必要があります。

  1. インデックスを作成または更新して、データを格納する検索フィールドを定義します。

    POST https://[service name].search.windows.net/indexes?api-version=2024-07-01
    Content-Type: application/json
    api-key: [Search service admin key]
    {
        "name": "mysearchindex",
        "fields": [{
            "name": "rid",
            "type": "Edm.String",
            "key": true,
            "searchable": false
        }, 
        {
            "name": "description",
            "type": "Edm.String",
            "filterable": false,
            "searchable": true,
            "sortable": false,
            "facetable": false,
            "suggestions": true
        }
      ]
    }
    
  2. ドキュメント キー フィールド ("key": true) を作成します。 パーティション分割されたコレクションの場合、既定のドキュメント キーは Azure Cosmos DB の _rid プロパティですが、フィールド名の先頭にはアンダースコア文字を使用できないため、これは Azure AI Search によって rid に自動的に変更されます。 また、Azure Cosmos DB の _rid 値には、Azure AI Search キーでは無効な文字が含まれています。 そのため、_rid 値は Base64 でエンコードされます。

  3. さらに多くの検索可能なコンテンツを使用する場合は、フィールドをさらに作成します。 詳細については、インデックスの作成に関するページを参照してください。

マッピング データ型

JSON データ型 Azure AI Search のフィールドの型
Bool Edm.Boolean、Edm.String
整数などの数値 Edm.Int32、Edm.Int64、Edm.String
浮動小数点などの数値 Edm.Double、Edm.String
String Edm.String
["a", "b", "c"] などのプリミティブ型の配列 Collection(Edm.String)
日付などの文字列 Edm.DateTimeOffset、Edm.String
{ "type": "Point", "coordinates": [long, lat] } などの GeoJSON オブジェクト Edm.GeographyPoint
その他の JSON オブジェクト 該当なし

Azure Cosmos DB for NoSQL インデクサーを構成して実行する

インデックスとデータ ソースを作成したら、インデクサーを作成できます。 インデクサーの構成では、実行時の動作を制御する入力、パラメーター、プロパティを指定します。

  1. 名前を指定し、データ ソースとターゲット インデックスを参照することで、インデクサーを作成または更新します。

    POST https://[service name].search.windows.net/indexers?api-version=2024-07-01
    Content-Type: application/json
    api-key: [search service admin key]
    {
        "name" : "[my-cosmosdb-indexer]",
        "dataSourceName" : "[my-cosmosdb-ds]",
        "targetIndexName" : "[my-search-index]",
        "disabled": null,
        "schedule": null,
        "parameters": {
            "batchSize": null,
            "maxFailedItems": 0,
            "maxFailedItemsPerBatch": 0,
            "base64EncodeKeys": false,
            "configuration": {}
            },
        "fieldMappings": [],
        "encryptionKey": null
    }
    
  2. フィールドの名前または種類に違いがある、または検索インデックスで複数のソース フィールドのバージョンが必要な場合、フィールド マッピングを定義します。

  3. その他のプロパティについては、「インデクサーの作成方法」を参照してください。

インデクサーは、作成されると自動的に実行されます。 これを防ぐには、"disabled" を true に設定します。 インデクサーの実行を制御するには、インデクサーをオンデマンドで実行するか、スケジュールを設定します。

インデクサーの状態を確認する

インデクサーの状態と実行履歴を監視するには、Azure portal 内でインデクサーの実行履歴を確認するか、Get Indexer Status REST API 要求を送信します

  1. [Search Service] ページ上で、[検索管理]>[インデクサー] を開きます。

  2. インデクサーを選択して、[構成] と [実行履歴] にアクセスします。

  3. 特定のインデクサー ジョブを選択して、詳細、警告、エラーを表示します。

実行履歴には、最近完了した実行 50 件が含まれます。時系列の逆の順に並べられるため、最後の実行が最初に表示されます。

新規および変更されたドキュメントのインデックス作成

インデクサーで検索インデックスが完全に設定されたら、以降のインデクサーで、データベース内の新規および変更されたドキュメントだけのインデックスを増分的に作成することができます。

増分インデックス作成を有効にするには、データ ソース定義で "dataChangeDetectionPolicy" プロパティを設定します。 このプロパティで、データに対して使用する変更追跡メカニズムをインデクサーに指示します。

Azure Cosmos DB インデクサーの場合、唯一サポートされているポリシーは、Azure Cosmos DB によって指定される _ts (timestamp) プロパティを使用する HighWaterMarkChangeDetectionPolicy です。

次の例は、変更検出ポリシーを含むデータ ソース定義を示しています。

"dataChangeDetectionPolicy": {
    "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
"  highWaterMarkColumnName": "_ts"
},

Note

Azure Cosmos DB のフィールドに null 値を割り当てると、AI Search インデクサーは null とフィールド値の欠落を区別できません。 そのため、インデックス内のフィールドが空の場合、その変更がデータベース内で行われた場合でも、null 値で置き換えられません。

増分インデックス作成とカスタム クエリ

ドキュメントを取得するためにカスタム クエリを使用している場合は、そのクエリで結果が _ts 列の順に並べ替えられていることを確認してください。 こうすることで Azure AI Search が使用する定期的なチェックポイントが作成され、エラーが発生した場合に増分の進行状況を利用できます。

ただし状況によっては、クエリに ORDER BY [collection alias]._ts 句が含まれる場合でも、クエリ結果が _ts で並べ替えられることを Azure AI Search で推論されない可能性があります。 assumeOrderByHighWaterMarkColumn 構成プロパティの設定で結果が並べ替えられるように Azure AI Search に指示することもできます。

このヒントを指定するには、次のようにインデクサー定義を作成または更新します。

{
    ... other indexer definition properties
    "parameters" : {
        "configuration" : { "assumeOrderByHighWaterMarkColumn" : true } }
} 

削除されたドキュメントのインデックス作成

コレクションから行が削除されると、通常、検索インデックスからも同様に行を削除する必要があります。 データ削除の検出ポリシーの目的は、削除されたデータ項目を効率的に識別することです。 現在、唯一サポートされているポリシーは、Soft Delete ポリシー (削除されると何らかのフラグでマークされる) です。これは、データ ソース定義で次のように指定します。

"dataDeletionDetectionPolicy"": {
    "@odata.type" : "#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
    "softDeleteColumnName" : "the property that specifies whether a document was deleted",
    "softDeleteMarkerValue" : "the value that identifies a document as deleted"
}

カスタム クエリを使用している場合、softDeleteColumnName で参照されるプロパティがクエリによってプロジェクションされていることを確認してください。

softDeleteColumnName はインデックス内の最上位のフィールドである必要があります。 複合データ型内での入れ子になったフィールドを softDeleteColumnName として使用することはサポートされていません。

次の例では、ソフト削除ポリシーとともにデータ ソースを作成します。

POST https://[service name].search.windows.net/datasources?api-version=2024-07-01
Content-Type: application/json
api-key: [Search service admin key]

{
    "name": "[my-cosmosdb-ds]",
    "type": "cosmosdb",
    "credentials": {
        "connectionString": "AccountEndpoint=https://[cosmos-account-name].documents.azure.com;AccountKey=[cosmos-account-key];Database=[cosmos-database-name]"
    },
    "container": { "name": "[my-cosmos-collection]" },
    "dataChangeDetectionPolicy": {
        "@odata.type": "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy",
        "highWaterMarkColumnName": "_ts"
    },
    "dataDeletionDetectionPolicy": {
        "@odata.type": "#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
        "softDeleteColumnName": "isDeleted",
        "softDeleteMarkerValue": "true"
    }
}

.NET の使用

SQL API プロトコルを介してアクセスされるデータの場合、.NET SDK を使用してインデクサーで自動化することができます。 これまでの REST API セクションを確認し、概念、ワークフロー、要件を理解することをお勧めします。 その後、次の .NET API リファレンス ドキュメントを参照して、マネージド コードで JSON インデクサーを実装できます。

次のステップ

これで、インデクサーの実行状態の監視インデクサーの実行のスケジュール設定をどのように行うか制御できるようになりました。 次の記事は、Azure Cosmos DB からコンテンツをプルするインデクサーに適用されます。