Azure AI Search インデクサーを使用したフィールド マッピングと変換

インデクサーのステージ

この記事では、サポートされているデータ ソースのソース フィールドと検索インデックスのターゲット フィールド間のデータ パスを確立する明示的なフィールドのマッピングを設定する方法について説明します。

フィールドのマッピングを設定するタイミング

Azure AI 検索インデクサーが検索インデックスを読み込むと、ソースから宛先へのフィールド マッピングを使用してデータ パスが決定されます。 暗黙的なフィールド マッピングは内部的なものであり、フィールド名とデータ型がソースと宛先の間で互換性がある場合に発生します。 入力と出力が一致しない場合は、この記事で説明するように、明示的な "フィールド マッピング" を定義してデータ パスを設定できます。

フィールド マッピングは、マッピング関数を使用して、エンコードまたはデコードなどの軽量のデータ変換にも使用することができます。 もっと多くの処理が必要な場合は、ギャップを埋めるために Azure Data Factory を検討してください。

フィールド マッピングの適用先は次のとおりです。

  • データ パスの両側の物理データ構造。 スキルによって作成された論理データ構造はメモリ内にのみ存在します。 outputFieldMappings を使用して、メモリ内ノードを検索インデックスの出力フィールドにマップします。

  • 親 AI 検索インデックスのみ。 "子" ドキュメントまたは "チャンク" を含む "セカンダリ" インデックスについては、高度なフィールド マッピング シナリオを参照してください。

  • 最上位の検索フィールドのみ。targetFieldName は単純なフィールドまたはコレクションのどちらかです。 ターゲット フィールドを複合型にすることはできません。

サポートされるシナリオ

インデクサー駆動のインデックス作成にサポートされているデータ ソースを使用していることを確認します。

ユース ケース 説明
名前の不一致 データ ソースに _city という名前のフィールドがあるとします。 Azure AI Search ではアンダースコアで始まるフィールド名が許可されていないため、フィールド マッピングを使用すると、「_city」 を 「city」 に効果的にマップできます。

複数のデータ ソースからコンテンツを取得することがインデックス作成要件に含まれていて、フィールド名がソースによって異なる場合、フィールド マッピングを使用すればパスが明確になります。
型の不一致 ソースの整数フィールドを、検索インデックスで検索できるよう Edm.String 型にしたいとします。 型が異なるため、このデータ パスを成功させるには、フィールド マッピングを定義する必要があります。 Azure AI Search では、多くのデータ ソースよりも サポートされているデータ型のセットが小さいことに注意してください。 SQL データをインポートする場合、フィールド マッピングを使用して、検索インデックスで必要な SQL データ型をマップできます。
1 対多のデータ パス インデックス内の複数のフィールドに対し、同じソース フィールドからコンテンツを投入できます。 たとえば、クライアント アプリでさまざまなユース ケースをサポートするために、各フィールドに異なるアナライザーを適用できます。
エンコーディングとデコーディング マッピング関数を適用して、インデックス作成中のデータの Base64 エンコードまたはデコードをサポートできます。
文字列を分割する、または配列を再キャストしてコレクションにする マッピング関数を適用して、区切り記号を含む文字列を分割したり、JSON の配列を Collection(Edm.String) 型の検索フィールドに送ったりすることができます。

Note

フィールド マッピングがない場合、インデクサーでは、データ ソースのフィールドを同じ名前のインデックス フィールドにマップする必要があると想定されます。 フィールド マッピングを追加すると、ソースとターゲットのフィールドに対するこれらの既定のフィールド マッピングはオーバーライドされます。 Blob Storage インデクサーなどの一部のインデクサーを使用すると、自動的にインデックス キー フィールドに対して既定のフィールドのマッピングが追加されます。

フィールドのマッピングでは、複合フィールドはサポートされていません。 既定のマッピングが機能するには、ソース構造 (ネスト構造または階層構造) がインデックス内の複合型と完全に一致する必要があります。 詳細については、入れ子になった JSON BLOB のインデックスの作成に関するチュートリアルの例を参照してください。 "Field mapping specifies target field 'Address/city' that doesn't exist in the index" のようなエラーが発生する場合は、ターゲットのフィールドマッピングを複合型にすることができないためです。

必要に応じて、複雑な構造から一部のノードだけを取得することもできます。 個別のノードを取得するには、入力データを文字列コレクションにフラット化してください (この回避策については、outputFieldMappings を参照)。

フィールド マッピングを定義する

このセクションでは、フィールドのマッピングを設定する手順について説明します。

  1. インデクサーの作成またはインデクサーの作成または更新、または Azure SDK の同等のメソッドを参照してください。 インデクサー定義の例を次に示します。

    {
       "name": "myindexer",
       "description": null,
       "dataSourceName": "mydatasource",
       "targetIndexName": "myindex",
       "schedule": { },
       "parameters": { },
       "fieldMappings": [],
       "disabled": false,
       "encryptionKey": { }
     }
    
  2. fieldMappings 配列に値を入力してマッピングを指定します。 フィールド マッピングは、3 つの部分で構成されます。

    "fieldMappings": [
      {
        "sourceFieldName": "_city",
        "targetFieldName": "city",
        "mappingFunction": null
      }
    ]
    
    プロパティ 説明
    sourceFieldName 必須。 データ ソース内のフィールドを表します。
    targetFieldName 省略可能。 検索インデックス内のフィールドを表します。 省略すると、ターゲットには sourceFieldName の値がみなされます。 ターゲット フィールドは、最上位の単純なフィールドまたはコレクションである必要があります。 複合型や複合コレクションにすることはできません。 データ型の問題を処理する場合、フィールドのデータ型はインデックス定義で指定されています。 フィールド マッピングに必要なのはフィールドの名前だけです。
    mappingFunction 省略可能。 データを変換する定義済みの関数で構成されます。

例: 名前または型の不一致

明示的なフィールドのマッピングにより、名前と型が同一でない場合のデータ パスが確立されます。

Azure AI Search では、大文字と小文字を区別しない比較を使用して、フィールド マッピングのフィールド名と関数名を解決します。 これは便利ですが (大文字と小文字を区別する必要がないため)、同時に、データ ソースまたはインデックスが、大文字と小文字のみが異なるフィールドを持つことができないことを意味します。

PUT https://[service name].search.windows.net/indexers/myindexer?api-version=[api-version]
Content-Type: application/json
api-key: [admin key]
{
    "dataSourceName" : "mydatasource",
    "targetIndexName" : "myindex",
    "fieldMappings" : [ { "sourceFieldName" : "_city", "targetFieldName" : "city" } ]
}

例: 一対多またはフォークされたデータ パス

この例では、1 つのソース フィールドを複数のターゲット フィールドにマッピング ("一対多" マッピング) します。 フィールドを "フォーク" し、同じソース フィールドの内容を、インデックス内の、分析方法や属性が異なる 2 つのフィールドにコピーできます。


"fieldMappings" : [
    { "sourceFieldName" : "text", "targetFieldName" : "textStandardEnglishAnalyzer" },
    { "sourceFieldName" : "text", "targetFieldName" : "textSoundexAnalyzer" }
]

スキルによって生成されたコンテンツにも同様のアプローチを使用できます。

マッピング関数と例

フィールド マッピング関数によって、インデックスに格納される前にフィールドのコンテンツが変換されます。 現在、以下のマッピング関数がサポートされています。

現時点では、これらの関数は親インデックスでのみサポートされることに注意してください。 これらはチャンク インデックス マッピングと互換性がないため、これらの関数をインデックス プロジェクションに使用することはできません。

base64Encode 関数

入力文字列の URL の安全な Base64 エンコードを実行します。 入力は UTF-8 でエンコードされていることを前提としています。

例: ドキュメント キーの基本エンコード

Azure AI Search ドキュメント キーには URL セーフな文字のみを使用できます ( 検索回数 APIを使用してドキュメントをアドレス指定できるようにします)。 キーのソース フィールドに、URL の安全ではない文字 (-\ など) が含まれている場合は、インデックス作成時に base64Encode 関数を使用して、変換することができます。

次の例では、サポートされていない文字を処理するために、metadata_storage_name に対して base64Encode 関数が指定されています。

PUT /indexers?api-version=2024-07-01
{
  "dataSourceName" : "my-blob-datasource ",
  "targetIndexName" : "my-search-index",
  "fieldMappings" : [
    { 
        "sourceFieldName" : "metadata_storage_name", 
        "targetFieldName" : "key", 
        "mappingFunction" : { 
            "name" : "base64Encode",
            "parameters" : { "useHttpServerUtilityUrlTokenEncode" : false }
        } 
    }
  ]
}

ドキュメント キー (変換前と変換後の両方) を 1,024 文字より長くすることはできません。 検索時にエンコードされたキーを取得するときは、base64Decode 関数を使用して元のキー値を取得し、それを使用してソース ドキュメントを取得します。

例: 基本エンコード フィールドを "検索可能" にする

metadata_storage_path のようなフィールドのエンコードされたバージョンをキーとして使用する必要がある一方で、フル テキスト検索にはエンコードされていないバージョンが必要になることもあります。 両方のシナリオをサポートするために、metadata_storage_path を 2 つのフィールドにマップすることができます。1 つは (エンコードされた) キー用で、もう 1 つはインデックス スキーマで searchable に属すると想定することができるパス フィールド用です。

PUT /indexers/blob-indexer?api-version=2024-07-01
{
    "dataSourceName" : " blob-datasource ",
    "targetIndexName" : "my-target-index",
    "schedule" : { "interval" : "PT2H" },
    "fieldMappings" : [
        { "sourceFieldName" : "metadata_storage_path", "targetFieldName" : "key", "mappingFunction" : { "name" : "base64Encode" } },
        { "sourceFieldName" : "metadata_storage_path", "targetFieldName" : "path" }
      ]
}

例 - 元の値を保持する

フィールド マッピングが指定されていない場合、Blob Storage インデクサーによって自動的に metadata_storage_path(BLOB の URI) からインデックス キー フィールドにフィールド マッピングが追加されます。 この値は Base64 でエンコードされているため、Azure AI Search ドキュメント キーとして安全に使用できます。 次の例では、URL が安全な Base64 によってエンコードされたバージョンの metadata_storage_pathindex_key フィールドにマップして、同時に、metadata_storage_path フィールドで元の値を保持する方法を示します。

"fieldMappings": [
  {
    "sourceFieldName": "metadata_storage_path",
    "targetFieldName": "metadata_storage_path"
  },
  {
    "sourceFieldName": "metadata_storage_path",
    "targetFieldName": "index_key",
    "mappingFunction": {
       "name": "base64Encode"
    }
  }
]

マッピング関数に parameters プロパティを含めない場合、既定で値 {"useHttpServerUtilityUrlTokenEncode" : true} になります。

Azure AI Search では、2 つの異なる Base64 エンコードがサポートされています。 同じフィールドをエンコードおよびデコードするときは、同じパラメーターを使用する必要があります。 詳細については、base64 エンコード オプションに関するページを参照して使用するパラメーターを決定します。

base64Decode 関数

入力文字列の Base64 デコードを実行します。 入力値は URL 対応の Base64 でエンコードされた文字列と想定されます。

例 - BLOB メタデータまたは URL をデコードする

ソース データには、BLOB メタデータ文字列や Web URL など、プレーン テキストとして検索できるようにする Base64 エンコード文字列が含まれている場合があります。 検索インデックスを設定するときに、base64Decode 関数を使用して、エンコードされたデータを通常の文字列に戻すことができます。

"fieldMappings" : [
  {
    "sourceFieldName" : "Base64EncodedMetadata",
    "targetFieldName" : "SearchableMetadata",
    "mappingFunction" : { 
      "name" : "base64Decode", 
      "parameters" : { "useHttpServerUtilityUrlTokenDecode" : false }
    }
  }
]

parameters プロパティを含めない場合、既定で値 {"useHttpServerUtilityUrlTokenEncode" : true} になります。

Azure AI Search では、2 つの異なる Base64 エンコードがサポートされています。 同じフィールドをエンコードおよびデコードするときは、同じパラメーターを使用する必要があります。 詳細については、base64 エンコード オプションに関するページを参照して使用するパラメーターを決定します。

base64 エンコード オプション

Azure AI Search では、URL セーフな base64 エンコードと通常の base64 エンコードがサポートされています。 インデックス作成中に base64 でエンコードされた文字列は、後で同じエンコード オプションでデコードする必要があります。そうしないと、結果が元の文字列と一致しなくなります。

それぞれがエンコードとデコードに対応する useHttpServerUtilityUrlTokenEncode パラメーターまたは useHttpServerUtilityUrlTokenDecode パラメーターが true に設定されると、base64EncodeHttpServerUtility.UrlTokenEncode のように、base64DecodeHttpServerUtility.UrlTokenDecode のように動作します。

警告

キー値を生成するために base64Encode を使用する場合は、useHttpServerUtilityUrlTokenEncode を true に設定する必要があります。 キー値に使用できるのは、URL セーフな base64 エンコードのみです。 キー値の文字に関するすべての制限事項については、名前付け規則に関する記事をご覧ください。

Azure AI Search の .NET ライブラリは、組み込みのエンコードを提供する完全な .NET Framework を前提としています。 useHttpServerUtilityUrlTokenEncodeuseHttpServerUtilityUrlTokenDecode オプションは、この組み込み機能を適用します。 .NET Core または別のフレームワークを使用している場合は、これらのオプションを false に設定し、フレームワークのエンコードおよびデコード関数を直接呼び出すことをお勧めします。

次の表では、文字列 00>00?00 の異なる base64 エンコードを比較しています。 base64 関数に必要な処理 (ある場合) を判断するには、ライブラリ エンコード関数を文字列 00>00?00 に適用し、出力を想定出力 MDA-MDA_MDA と比較します。

[エンコード] base64 エンコード出力 ライブラリ エンコード後の追加処理 ライブラリ デコード前の追加処理
パディング付きの base64 MDA+MDA/MDA= URL で使用できる文字を使用し、パディングを削除する 標準 base64 文字を使用し、パディングを追加する
パディングなしの base64 MDA+MDA/MDA URL で使用できる文字を使用する 標準 base64 文字を使用する
パディング付きの URL 対応 base64 MDA-MDA_MDA= パディングを削除する パディングを追加する
パディングなしの URL 対応 base64 MDA-MDA_MDA なし なし

extractTokenAtPosition 関数

指定された区切り記号を使用して文字列フィールドを分割し、結果として得られる分割の指定位置でトークンを取得します。

この関数は以下のパラメーターを使用します。

  • delimiter: 入力文字列を分割するときに区切り記号として使用する文字列。
  • position: 入力文字列の分割後に取得するトークンの整数の 0 から始まる位置。

たとえば、入力が Jane Doedelimiter" " (空白)、position が 0 の場合、結果は Jane になり、position が 1 の場合、結果は Doe になります。 位置が、存在しないトークンを参照する場合、エラーが返されます。

例 - 名前を抽出する

データ ソースに PersonName フィールドが含まれ、それを 2 つの別々の FirstName および LastName フィールドとしてインデックスする必要がある場合、 この関数を使用して、空白文字を区切り記号として使って入力を分割できます。

"fieldMappings" : [
  {
    "sourceFieldName" : "PersonName",
    "targetFieldName" : "FirstName",
    "mappingFunction" : { "name" : "extractTokenAtPosition", "parameters" : { "delimiter" : " ", "position" : 0 } }
  },
  {
    "sourceFieldName" : "PersonName",
    "targetFieldName" : "LastName",
    "mappingFunction" : { "name" : "extractTokenAtPosition", "parameters" : { "delimiter" : " ", "position" : 1 } }
  }]

jsonArrayToStringCollection 関数

文字列の JSON 配列として書式設定された文字列を、インデックス内の Collection(Edm.String) フィールドの入力に使用できる文字列配列に変換します。

たとえば、入力文字列が ["red", "white", "blue"] の場合、Collection(Edm.String) 型のターゲット フィールドに redwhiteblue の 3 つの値が設定されます。 JSON 文字列配列として解析できない入力値では、エラーが返されます。

例 - リレーショナル データからコレクションを設定する

Azure SQL Database には、Azure AI Search の Collection(Edm.String) フィールドに自然にマップされる組み込みのデータ型はありません。 文字列収集フィールドを設定するには、ソース データを JSON 文字列配列として前処理してから、jsonArrayToStringCollection マッピング関数を使用することができます。

"fieldMappings" : [
  {
    "sourceFieldName" : "tags", 
    "mappingFunction" : { "name" : "jsonArrayToStringCollection" }
  }]

urlEncode 関数

この関数を使用すると、"URL セーフ" になるように文字列をエンコードできます。 URL 内で許可されていない文字を含む文字列と共に使用する場合、この関数では、これらの "安全でない" 文字が等価の文字エンティティに変換されます。 この関数では、UTF-8 エンコード形式が使用されます。

例 - ドキュメント キーの検索

urlEncode 関数は、他の文字をそのままにして、URL の安全でない文字だけを変換する場合に、base64Encode 関数の代わりに使用できます。

たとえば、入力文字列が <hello> の場合、(Edm.String) 型のターゲット フィールドに値 %3chello%3eが設定されます

検索時にエンコードされたキーを取得すると、urlDecode 関数を使用して元のキー値を取得し、それを使用してソース ドキュメントを取得できます。

"fieldMappings" : [
  {
    "sourceFieldName" : "SourceKey",
    "targetFieldName" : "IndexKey",
    "mappingFunction" : {
      "name" : "urlEncode"
    }
  }
]

urlDecode 関数

この関数では、UTF-8 エンコード形式を使用して、URL エンコードされた文字列がデコードされた文字列に変換されます。

例 - BLOB メタデータをデコードする

一部の Azure ストレージ クライアントでは、ASCII 以外の文字が含まれている場合に、BLOB メタデータが自動的に URL エンコードされます。 ただし、このようなメタデータを (プレーンテキストとして) 検索可能にする場合は、urlDecode 関数を使用して、検索インデックスを設定する際に、エンコードされたデータを通常の文字列に戻すことがきます。

"fieldMappings" : [
  {
    "sourceFieldName" : "UrlEncodedMetadata",
    "targetFieldName" : "SearchableMetadata",
    "mappingFunction" : {
      "name" : "urlDecode"
    }
  }
]

fixedLengthEncode 関数

この関数を使用すると、任意の長さの文字列が固定長文字列に変換されます。

例 - 長すぎるドキュメント キーをマップする

1024 文字を超えるドキュメント キーの長さに関連するエラーが発生した場合、この関数を適用して、ドキュメント キーの長さを短くすることができます。


"fieldMappings" : [
 {
   "sourceFieldName" : "metadata_storage_path",
   "targetFieldName" : "your key field",
   "mappingFunction" : {
     "name" : "fixedLengthEncode"
   }
 }
]

toJson 関数

この関数は、文字列を書式設定された JSON オブジェクトに変換します。 これは、Azure SQL などのデータ ソースが複合または階層データ型をネイティブにサポートしないシナリオで使用し、それを複合フィールドにマップすることができます。

例 - テキスト コンテンツを複合フィールドにマップする

インデックス内の (対応して定義された) 複合フィールドにマップする必要がある JSON 文字列を含んだ SQL 行があるとしましょう。toJson 関数を使用すると、これを実現することができます。 たとえば、インデックス内の複合フィールドに次のデータを設定する必要がある場合です。

{
    "id": "5",
    "info": {
        "name": "Jane",
        "surname": "Smith",
        "skills": [
            "SQL",
            "C#",
            "Azure"
        ],
        "dob": "2005-11-04T12:00:00"
    }
}

これは、{"id": 5, "info": {"name": "Jane", "surname": "Smith", "skills": ["SQL", "C#", "Azure"]}, "dob": "2005-11-04T12:00:00"} のような SQL 行内の JSON 文字列の列に対して、toJson マッピング関数を使用して実現することができます。

このフィールド マッピングは以下に示すように指定する必要があります。


"fieldMappings" : [
  {
    "sourceFieldName" : "content",
    "targetFieldName" : "complexField",
    "mappingFunction" : {
      "name" : "toJson"
    }
  }
]

高度なフィールド マッピング シナリオ

データ チャンクや分割などの "一対多" のドキュメント リレーションシップがあるシナリオで、親ドキュメントから "子" ドキュメント (チャンク) にフィールドをマッピングするには、次のガイドラインに従ってください。

1.親ドキュメントのインデックス作成のスキップ

親ドキュメントのインデックス作成をスキップする場合 (スキルセットの indexProjectionsprojectionModeskipIndexingParentDocuments に設定する)、インデックス プロジェクションを使用して、親ドキュメントから "子" ドキュメントにフィールドをマッピングします。

2.親ドキュメントと "子" ドキュメントの両方のインデックス作成

親ドキュメントと "子" ドキュメントの両方にインデックスを作成する場合:

  • フィールド マッピングを使用して、親ドキュメントにフィールドをマッピングします。
  • インデックス プロジェクションを使用して、"子" ドキュメントにフィールドをマッピングします。

3.関数で変換された値の親ドキュメントまたは "子" ドキュメントへのマッピング

親ドキュメント内のフィールドに変換 (エンコードなどのマッピング関数を使用する) が必要で、親ドキュメントまたは "子" ドキュメントにマッピングする必要がある場合:

  • インデクサーでフィールド マッピングの関数を使用して変換を適用します。
  • スキルセットのインデックス プロジェクションを使用して、変換されたフィールドを "子" ドキュメントにマッピングします。

関連項目