大文字と小文字を区別しないフィルター処理、ファセット、並べ替えのためのテキスト正規化

Azure AI 検索では、normalizer は、"フィルター可能"、"ファセット可能"、または "並べ替え可能" としてマークされたフィールドに対するキーワード 照合のテキストを前処理するコンポーネントです。 テキスト アナライザーと組み合わせて使用されるフルテキスト "検索可能" フィールドとは対照的に、filter-facet-sort 操作用に作成されたコンテンツは分析やトークン化を行いません。 テキスト分析を省略すると、大文字と小文字の違いが表示されたときに予期しない結果が生じる可能性があります。このため、コンテンツのバリエーションを均一化するためにノーマライザーが必要です。

ノーマライザーを適用することで、結果を向上させる簡易テキスト変換を実現できます。

  • 一貫性のある大文字小文字の区別 (すべて小文字や大文字など)
  • ö や ê などのアクセント記号と分音記号を ASCII の等価文字 "o" と "e" に正規化する
  • -や空白などの文字をユーザー指定の文字にマップする

ノーマライザーの利点

検索インデックスからドキュメントを検索および取得するには、クエリ入力をドキュメントの内容と照合する必要があります。 "検索" を呼び出す場合と同様に、トークン化されたコンテンツに対して照合するか、要求が フィルターファセット、または orderby 操作である場合はトークン化されていないコンテンツを介して照合します。

トークン化されていないコンテンツも分析されないため、コンテンツの小さな違いは明確に異なる値として評価されます。 次の例を考えてみましょう。

  • $filter=City eq 'Las Vegas' では、正確なテキスト "Las Vegas" を含むドキュメントのみが返され、 "LAS VEGAS""las vegas"を含むドキュメントは除外されます。大文字と小文字に関係なく、ユース ケースですべてのドキュメントが必要な場合は不十分です。

  • search=*&facet=City,count:5 は、同じ都市であるにもかかわらず、 "Las Vegas""LAS VEGAS" 、および "las vegas" を個別の値として返します。

  • search=usa&$orderby=City は、大文字か小文字かに関係なく、同じ都市をまとめて並べたいという意図であったとしても、""Las Vegas""、""Seattle""、""las vegas"" という辞書式順序で都市を返します。

インデックス作成とクエリの実行中に呼び出されるノーマライザーは、フィルター、ファセット、並べ替えのシナリオでテキストの小さな違いを滑らかにするライト変換を追加します。 前の例では、 "Las Vegas" のバリアントは、選択したノーマライザー (たとえば、すべてのテキストが小文字) に従って処理され、より一様な結果が得られます。

ノーマライザーを指定する方法

ノーマライザーは、少なくとも 1 つの "フィルター可能"、"並べ替え可能"、または "ファセット可能" プロパティが true に設定されているテキスト フィールド (Edm.StringCollection(Edm.String)) で、フィールドごとにインデックス定義で指定されます。 ノーマライザーの設定は省略可能であり、既定では null です。 カスタムノーマライザーを構成する前に、定義済みのノーマライザーを評価することをお勧めします。

ノーマライザーは、インデックスに新しいフィールドを追加する場合にのみ指定できます。そのため、可能であれば、インデックスの削除と再作成がルーチンである場合は、開発の初期段階で正規化のニーズを事前に評価し、ノーマライザーを割り当ててみてください。

  1. インデックスでフィールド定義を作成する場合は、"normalizer" プロパティを次のいずれかの値に設定します。"小文字" などの定義済みのノーマライザー、またはカスタム ノーマライザー (同じインデックス スキーマで定義)。

    "fields": [
     {
       "name": "Description",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "filterable": true,
       "analyzer": "en.microsoft",
       "normalizer": "lowercase"
       ...
     }
    ]
    
  2. カスタム ノーマライザーは、最初にインデックスの "ノーマライザー" セクションで定義され、次に前の手順に示すようにフィールド定義に割り当てられます。 詳細については、「インデックスの 作成 」および 「カスタム ノーマライザーの追加」を参照してください。

    "fields": [
     {
       "name": "Description",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": null,
       "normalizer": "my_custom_normalizer"
     },
    

メモ

既存のフィールドのノーマライザーを変更するには、 インデックスを 完全に再構築します (個々のフィールドを再構築することはできません)。

インデックスの再構築にコストがかかる運用インデックスの回避策として、古いフィールドと同じ新しいフィールドを作成し、新しいノーマライザーを使用して、古いフィールドの代わりに使用することをお勧めします。 インデックスの更新を使用して新しいフィールドを組み込み、mergeOrUpload を使用してデータを設定します。 後で、計画的なインデックス サービスの一環として、インデックスをクリーンアップして古いフィールドを削除できます。

定義済みノーマライザーとカスタム ノーマライザー

Azure AI 検索では、一般的なユース ケース用の組み込みのノーマライザーと、必要に応じてカスタマイズする機能が提供されます。

カテゴリ 説明
定義済みのノーマライザー すぐに使用でき、構成なしで使用できます。
カスタム ノーマライザー1 高度なシナリオの場合。 char フィルターとトークン フィルターで構成される既存の要素の組み合わせのユーザー定義構成が必要です。

(1) ノーマライザーは常に 1 つのトークンを生成するため、カスタム ノーマライザーはトークナイザーを指定しません。

ノーマライザーをテストする

Test Analyzer (REST) を使用して、ノーマライザーが入力を処理する方法を確認できます。

要求

  POST https://[search service name].search.windows.net/indexes/[index name]/analyze?api-version=[api-version]
    Content-Type: application/json
    api-key: [admin key]

  {
     "normalizer":"asciifolding",
     "text": "Vis-à-vis means Opposite"
  }

応答

HTTP/1.1 200 OK

{
  "tokens": [
    {
      "token": "Vis-a-vis means Opposite",
      "startOffset": 0,
      "endOffset": 24,
      "position": 0
    }
  ]
}

ノーマライザー リファレンス

定義済みのノーマライザー

名前 説明とオプション
標準 テキストを小文字に変換し、その後でasciifolding(ASCIIフォールディング)を適用します。
小文字 文字を小文字に変換します。
大文字 文字を大文字に変換します。
asciifolding Basic Latin Unicode ブロックに含まれていない文字を、ASCII に相当する文字 (存在する場合) に変換します。 たとえば、 àa に変更します。
elision トークンの先頭からエリジオンを削除します。

サポートされている文字フィルター

ノーマライザーは、カスタム アナライザーの文字フィルターで対応する文字フィルターと同じ 2 つの 文字フィルターをサポートします。

サポートされているトークン フィルター

次の一覧は、ノーマライザーでサポートされているトークン フィルターを示しています。これは、 カスタム アナライザーで使用されるトークン フィルター全体のサブセットです

カスタム ノーマライザーを追加する

カスタム ノーマライザーは、 インデックス スキーマ内で定義されます。 定義には、名前、型、1 つ以上の文字フィルター、およびトークン フィルターが含まれます。 文字フィルターとトークン フィルターは、カスタム ノーマライザーの構成要素であり、テキストの処理を担当します。 これらのフィルターは、左から右に適用されます。

token_filter_name_1はトークン フィルターの名前であり、char_filter_name_1char_filter_name_2は文字フィルターの名前です (有効な値については、サポートされているトークン フィルターサポートされている文字フィルターテーブルを参照してください)。

"normalizers":(optional)[
   {
      "name":"name of normalizer",
      "@odata.type":"#Microsoft.Azure.Search.CustomNormalizer",
      "charFilters":[
         "char_filter_name_1",
         "char_filter_name_2"
      ],
      "tokenFilters":[
         "token_filter_name_1"
      ]
   }
],
"charFilters":(optional)[
   {
      "name":"char_filter_name_1",
      "@odata.type":"#char_filter_type",
      "option1": "value1",
      "option2": "value2",
      ...
   }
],
"tokenFilters":(optional)[
   {
      "name":"token_filter_name_1",
      "@odata.type":"#token_filter_type",
      "option1": "value1",
      "option2": "value2",
      ...
   }
]

カスタム ノーマライザーは、インデックスの作成時または後で既存のものを更新することで追加できます。 既存のインデックスにカスタム ノーマライザーを追加するには、 Update Index で "allowIndexDowntime" フラグを指定する必要があります。これにより、インデックスは数秒間使用できなくなります。

カスタム ノーマライザーの例

次の例は、対応する文字フィルターとトークン フィルターを含むカスタム ノーマライザー定義を示しています。 文字フィルターとトークン フィルターのカスタム オプションは、名前付きコンストラクトとして個別に指定され、次に示すようにノーマライザー定義で参照されます。

  • "my_custom_normalizer" という名前のカスタム ノーマライザーは、インデックス定義の "ノーマライザー" セクションで定義されます。

  • ノーマライザーは、2 つの文字フィルターと 3 つのトークン フィルター (elision、小文字、カスタマイズされた asciifolding フィルター "my_asciifolding" で構成されます。

  • 最初の文字フィルター "map_dash" は、すべてのダッシュをアンダースコアに置き換え、2 つ目の "remove_whitespace" ではすべてのスペースを削除します。

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false,
        },
        {
           "name":"city",
           "type":"Edm.String",
           "filterable": true,
           "facetable": true,
           "normalizer": "my_custom_normalizer"
        }
     ],
     "normalizers":[
        {
           "name":"my_custom_normalizer",
           "@odata.type":"#Microsoft.Azure.Search.CustomNormalizer",
           "charFilters":[
              "map_dash",
              "remove_whitespace"
           ],
           "tokenFilters":[              
              "my_asciifolding",
              "elision",
              "lowercase",
           ]
        }
     ],
     "charFilters":[
        {
           "name":"map_dash",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["-=>_"]
        },
        {
           "name":"remove_whitespace",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["\\u0020=>"]
        }
     ],
     "tokenFilters":[
        {
           "name":"my_asciifolding",
           "@odata.type":"#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
           "preserveOriginal":true
        }
     ]
  }

関連項目