Azure AI Search でのインデックス プロジェクション

重要

インデックス プロジェクションは、追加使用条件の下でパブリック プレビュー段階にあります。 この機能を含むように更新された Azure portal 2023-10-01-Preview REST API、Azure portal、ベータ版クライアント ライブラリを通じて利用できます。

インデックス プロジェクションは、セカンダリ インデックスの形状を定義するスキルセット定義のコンポーネントであり、エンリッチメント パイプラインのコンテンツが複数のインデックスをターゲットにできる 1 対多のインデックス パターンをサポートしています。

インデックス プロジェクションでは、エンリッチメント パイプラインによって生成された AI エンリッチメントコンテンツを取得し、検索サービス上のセカンダリ インデックス (インデクサーが既定でターゲットとするものとは異なる) にインデックスを付けます。 インデックス プロジェクションを使用すると、エンリッチされた項目の配列をターゲット インデックス内の複数の検索ドキュメントに一意に分離 (すなわち "1 対多" インデックス付け) できる方法で、インデックスを付ける前にデータの形状を変更することもできます。 "1 対多" インデックス付けは、チャンクされていないコンテンツのプライマリ インデックスやチャンクされたコンテンツのセカンダリ インデックスが必要になったりする、データ チャンクのシナリオで役立ちます。

過去にコグニティブ スキルを使用したことがある場合は、エンリッチされたコンテンツがスキルセットによって作成されていることを既にご存知でしょう。 スキルセットは、エンティティの認識やテキストの翻訳など、アトミック変換を呼び出す一連のエンリッチメント通じてドキュメントを移動します。 既定では、スキルセット内で処理された 1 つのドキュメントは、検索インデックス内の 1 つのドキュメントにマッピングされます。 つまり、入力テキストのチャンクを実行し、各チャンクに対してエンリッチメントを実行すると、outputFieldMappings を使用してマッピングされた場合のインデックスの結果は、生成されたエンリッチメントの配列になります。 インデックス プロジェクションでは、エンリッチされたデータの各チャンクをそれ自体の検索ドキュメントにマッピングするコンテキストを定義します。 こうすることで、ドキュメントのエンリッチされたデータの 1 対多マッピングを検索インデックスに適用できます。

インデックス プロジェクションの定義

インデックス プロジェクションはスキルセット定義内で定義され、そして主にセレクターの配列として定義されます。この配列では、各セレクターが検索サービス上の異なるターゲット インデックスに対応します。 各セレクターには、定義の一部として次のパラメータが必要です。

  • targetIndexName: インデックス プロジェクション データのインデックスが付けられる検索サービスのインデックスの名前。
  • parentKeyFieldName: 親ドキュメントのキーの値が入ったターゲット インデックス内のフィールドの名前。
  • sourceContext: 個々の検索ドキュメントにデータをマッピングする細分性を定義するエンリッチメント注釈。 詳細については、「スキル コンテキストと入力注釈言語」を参照してください。
  • mappings: 検索インデックス内のフィールドへのエンリッチされたデータのマッピングの配列。 各マッピングは次で構成されます。
    • name: データのインデックスを付ける検索インデックス内のフィールドの名前。
    • source: データをプルするエンリッチメント注釈パス。

mapping では、ナレッジ ストアShaper スキルと同様に、オプションの sourceContext および inputs フィールドを使用してデータを再帰的に定義することもできます。 これらのパラメータを使用すると、検索インデックス内の Edm.ComplexType 型のフィールドにインデックスを付けるデータを整形できます。

targetIndexName パラメータで定義されるインデックスには、次の要件があります。

  • インデックス プロジェクション定義を含むスキルセットが作成される前に、検索サービスで既に作成されている必要がある。
  • parentKeyFieldName パラメータで定義されている名前が付いたフィールドを含む必要がある。 このフィールドは Edm.String 型である必要があり、キー フィールドにすることはできません。また、フィルター適用可否を true に設定する必要があります。
  • キー フィールドは、検索可否を true に設定し、keyword アナライザーで定義する必要があります。
  • mappings で定義されている各 name に対してフィールドを定義する必要があり、いずれもキー フィールドにはできない。

Split スキルによって出力された個々のページを、検索インデックス内のそれ自体のドキュメントとしてプロジェクションするのに使用する、インデックス プロジェクション定義のペイロードの例を次に示します。

"indexProjections": {
    "selectors": [
        {
            "targetIndexName": "myTargetIndex",
            "parentKeyFieldName": "ParentKey",
            "sourceContext": "/document/pages/*",
            "mappings": [
                {
                    "name": "chunk",
                    "source": "/document/pages/*"
                }
            ]
        }
    ]
}

親ドキュメントの処理

インデックス プロジェクションでは、スキルセットを介して実行される "親" ドキュメントごとに "子" ドキュメントが効果的に生成されるため、"親" ドキュメントのインデックス付けを処理する方法について次の選択肢もあります。

  • 親ドキュメントと子ドキュメントを別々のインデックスに保持するには、インデクサー定義の targetIndexName が、インデックス プロジェクション セレクターで定義されている targetIndexName とは異なるようにするだけです。

  • 親ドキュメントと子ドキュメントを同じインデックスにインデックス付けするには、ターゲット インデックスのスキーマが、インデクサー定義内の定義された fieldMappingsoutputFieldMappings の両方と、インデックス プロジェクション セレクターの mappings を使用して動作するようにする必要があります。 そして、インデクサー定義とインデックス プロジェクション セレクターに同じ targetIndexName を指定するだけです。

  • 親ドキュメントを無視し、子ドキュメントのインデックスのみを付けるには、インデクサー定義に targetIndexName を指定する必要があります (インデックス プロジェクション セレクターに対してと同じものを指定できます)。 次に、次に示すように、projectionMode キーを skipIndexingParentDocuments に設定して、selectors 定義の横にある別の parameters オブジェクトを定義します。

    "indexProjections": {
        "selectors": [
            ...
        ],
        "parameters": {
            "projectionMode": "skipIndexingParentDocuments"
        }
    }
    

REST API バージョン 2023-10-01-Preview を使用すると、スキルセットへの追加によりインデックス プロジェクションを作成できます。

コンテンツのライフサイクル

インデクサー データ ソースで変更の追跡と削除の検出がサポートされている場合、インデックス付けプロセスはプライマリ インデックスとセカンダリ インデックスを同期して、それらの変更を取得できます。

インデクサーとスキルセットを実行するたび、スキルセットまたは基になるソース データが変更された場合には、インデックス プロジェクションが更新されます。 インデクサーによって取得された変更は、エンリッチメント プロセスを通じてインデックス内のプロジェクションに反映され、プロジェクションされたデータが元のデータ ソース内のコンテンツの現在の表現になります。

Note

インデックス プッシュ API を使用して、プロジェクションされたドキュメント内のデータを手動で編集できますが、ソース データ内のドキュメントが更新された場合、次のパイプライン呼び出しですべての編集が上書きされます。

プロジェクションされるキーの値

各インデックス プロジェクション ドキュメントには、一意性を確保し、変更と削除の追跡を正しく機能させるために、インデクサーによって生成される一意の識別キーが含まれています。 このキーには、次のセグメントが含まれています。

  • 一意性を保証するランダム ハッシュ。 このハッシュは、親ドキュメントがインデクサーの実行間で更新された場合に変更されます。
  • 親ドキュメントのキー。
  • ドキュメントの生成元のコンテキストを識別するエンリッチメント注釈パス。

たとえば、キー値が "123" の親ドキュメントを 4 ページに分割し、それらの各ページがインデックス プロジェクションによりそれ自体のドキュメントとしてプロジェクションされる場合、テキストの 3 番目のページのキーは "01f07abfe7ed_123_pages_2" のようになります。 そして親ドキュメントが更新されて 5 ページ目が追加されると、3 番目のページの新しいキーが "9d800bdacc0e_123_pages_2" などとなったりします。これは、残りのプロジェクション データが変更されなくても、インデクサーの実行間でランダム ハッシュ値が変更されるためです。

変更または追加

プロジェクションされたインデックス ドキュメント内のデータが変更されるように親ドキュメントが変更された場合 (たとえば、1 語が特定のページで変更されたが、実質的に新しいページは追加されていない場合など)、その特定のプロジェクションのターゲット インデックス内のデータは、その変更を反映するように更新されます。

親ドキュメントが変更され、以前は存在していなかった新しいプロジェクションされた子ドキュメントができる場合 (たとえば、ドキュメントに 1 ページ以上に相当するテキストが追加された場合など)、その新しい子ドキュメントは、インデクサーが次回実行されるときに追加されます。

どちらの場合も、特定のコンテンツが更新されたかどうかに関係なく、すべてのプロジェクションされたドキュメントはキーに新しいハッシュ値を持つよう更新されます。

削除

親ドキュメントが変更され、インデックス プロジェクションによって生成された子ドキュメントが存在しなくなった場合 (たとえば、テキストを短くして以前よりチャンクが減った場合など)、検索インデックス内の対応する子ドキュメントは削除されます。 残りの子ドキュメントも、そのコンテンツが他に変更されていなくても、新しいハッシュ値を含むようにキーが更新されます。

親ドキュメントがデータソースから完全に削除された場合、対応する子ドキュメントは、データソース定義で定義された dataDeletionDetectionPolicy によって削除が検出された場合にのみ削除されます。 dataDeletionDetectionPolicy が構成されていなくて、データソースから親ドキュメントを削除する必要がある場合は、不要であれば子ドキュメントを手動で削除する必要があります。