Azure AI Search での Lucene クエリ構文

Azure AI Search でクエリを作成する場合、ワイルドカード、あいまい検索、近接検索、正規表現など、特殊なクエリ フォームに対して完全な Lucene Query Parser 構文を選択できます。 Lucene Query Parser 構文の多くは、Azure AI Search でそのまま実装されています。ただし、*範囲検索は例外で、これは $filter 式を使って構築されます。

完全な Lucene 構文を使用するには、queryType を full に設定し、ワイルドカード、あいまい検索、または完全な構文でサポートされている他のクエリ形式のいずれかのクエリ式を渡します。 REST では、クエリ式はドキュメントの検索 (REST API) 要求の search パラメーターで指定されます。

例 (完全な構文)

次の例は、完全な構文を使用して構成された検索要求です。 この特定の例では、フィールド内検索と用語ブーストが示されています。 カテゴリ フィールドに budget という用語が含まれているホテルを検索します。 "recently renovated" というフレーズを含むすべてのドキュメントは、用語ブースト値 (3) の結果、高いランキングになります。

POST /indexes/hotels-sample-index/docs/search?api-version=2023-11-01
{
  "queryType": "full",
  "search": "category:budget AND \"recently renovated\"^3",
  "searchMode": "all"
}

どのクエリの種類にも固有ではありませんが、この例では searchMode パラメーターが関連しています。 クエリに演算子があるときは、通常 searchMode=all を設定して、すべての条件が確実に一致するようにします。

その他の例については、Lucene クエリ構文の例に関する記事をご覧ください。 searchMode を含む、クエリ要求とパラメーターの詳細については、ドキュメントの検索 (REST API) に関するページを参照してください。

構文の基礎

次の構文の基礎は、Lucene 構文を使用するすべてのクエリに適用されます。

コンテキストでの演算子評価

配置によって、記号を演算子と解釈するか、または文字列内の 1 つの文字と解釈するかが決まります。

たとえば、Lucene の完全構文では、チルダ (~) はあいまい検索と近接検索の両方に使用されます。 引用符で囲まれた語句の後に配置されると、~ は近接検索を呼び出します。 用語の末尾に配置されると、~ はあいまい検索を呼び出します。

business~analyst のような用語内では、この文字は演算子として評価されません。 この場合は、このクエリが用語または語句のクエリであると想定して、字句解析を使用するフル テキスト検索によって ~ が削除され、business~analyst という用語は 2 つに分割されて、business OR analyst になります。

上記の例ではチルダ (~) ですが、すべての演算子に同じ原則が適用されます。

特殊文字のエスケープ

検索テキストの一部として検索演算子のいずれかを使用するには、文字の前に 1 つの円記号 (\) を付けることで文字をエスケープします。 たとえば、https:// のワイルドカード検索で、:// がクエリ文字列の一部である場合、search=https\:\/\/* を指定します。 同様に、エスケープされた電話番号パターンは、\+1 \(800\) 642\-7676 のようになります。

エスケープが必要な特殊文字には次の例があります。
+ - & | ! ( ) { } [ ] ^ " ~ * ? : \ /

Note

エスケープすることでトークンが一緒に保持されますが、インデックスを作成するときの字句解析で削除される場合があります。たとえば、標準の Lucene アナライザーでは、ハイフン、スペースなどの文字で単語が分割されます。 クエリ文字列で特殊文字が必要な場合は、それらをインデックスに保持するアナライザーが必要になることがあります。 選択肢には、ハイフンでつながれた単語を保持する Microsoft 自然言語アナライザーや、より複雑なパターン用のカスタム アナライザーなどが含まれます。 詳細については、部分的な語句、パターン、特殊文字に関する記事を参照してください。

URL での安全でない文字および予約文字のエンコード

安全でない文字および予約文字はすべて、URL でエンコードするようにしてください。 たとえば、# は、URL ではフラグメント ID またはアンカー ID であるため、安全な文字ではありません。 この文字を URL で使用する場合は、%23 にエンコードする必要があります。 &= は、予約文字の例です。これらの文字は、Azure AI Search でパラメーターを区切り、値を指定します。 詳しくは、RFC1738: Uniform Resource Locators (URL) に関するページをご覧ください。

安全でない文字は " ` < > # % { } | \ ^ ~ [ ] です。 予約文字は ; / ? : @ = + & です。

ブール演算子

照合の精度を向上させるために、クエリ文字列にブール演算子を埋め込むことができます。 完全な構文は、文字演算子に加え、テキスト演算子をサポートします。 テキスト ブール演算子 (AND、OR、NOT) は、常に大文字で指定します。

テキスト演算子 文字 使用方法
かつ + wifi AND luxury 照合で含める必要がある用語を指定します。 この例では、クエリ エンジンは wifiluxury の両方を含むドキュメントを検索します。 プラス文字 (+) を用語の直前に使用して、その用語を必須にすることもできます。 たとえば、+wifi +luxury は、両方の用語が 1 つのドキュメントのフィールド内のどこかに表示されている必要があることを規定します。
OR (なし) 1 wifi OR luxury いずれかの用語が見つかった場合に一致を検索します。 この例では、クエリ エンジンは、wifi または luxury のいずれか、あるいはその両方を含むドキュメントに対して一致を返します。 OR は、既定の結合演算子のため、除外することもできます。たとえば、wifi luxurywifi OR luxury と同等です。
NOT !- wifi –luxury 用語を除外するドキュメントに対して一致を返します。 たとえば、wifi –luxury を指定すると、wifi という用語を含むが、luxury を含まないドキュメントが検索されます。

1| 文字は、OR 演算ではサポートされていません。

NOT 論理演算子

重要

NOT 演算子 (NOT!、または -) は、完全な構文では、単純な構文とは異なる動作をします。

  • 単純な構文では、否定を含むクエリには常にワイルドカードが自動的に追加されます。 たとえば、クエリ -luxury は自動的に -luxury * に拡張されます。
  • 完全な構文では、否定を含むクエリをワイルドカードと組み合わせることはできません。 たとえば、クエリ -luxury * は使用できません。
  • 完全な構文では、否定が 1 つのクエリは使用できません。 たとえば、クエリ -luxury は使用できません。
  • 完全な構文では、否定は、検索モードに関係なく、常にクエリに AND が設定されているかのように動作します。
    • たとえば、完全な構文の完全な構文クエリ wifi -luxury では、wifi という用語を含むドキュメントのみがフェッチされたあと、それらのドキュメントに否定 -luxury が適用されます。
  • 否定を使用してインデックス内のすべてのドキュメントを検索する場合は、any 検索モードを使用した単純な構文をお勧めします。
  • 否定を使用してインデックス内のドキュメントのサブセットを検索する場合は、完全な構文、またはすべての検索モードを使用した単純な構文をお勧めします。
クエリの種類 検索モード サンプル クエリ Behavior
シンプル 任意 wifi -luxury インデックス内のすべてのドキュメントを返します。 "wifi" という用語を含むドキュメント、または "luxury" という用語が含まれていないドキュメントは、他のドキュメントよりも上位にランク付けされます。 クエリが wifi OR -luxury OR * に拡張されます。
シンプル すべて wifi -luxury "wifi" という用語を含み、"luxury" という用語を含まない、インデックス内のドキュメントのみを返します。 クエリが wifi AND -luxury AND * に拡張されます。
完全 任意 wifi -luxury "wifi" という用語を含むインデックス内のドキュメントのみを返し、"luxury" という用語を含むドキュメントが結果から削除されます。
完全 すべて wifi -luxury "wifi" という用語を含むインデックス内のドキュメントのみを返し、"luxury" という用語を含むドキュメントが結果から削除されます。

フィールド検索

fieldName:searchExpression 構文を使用して、フィールド検索操作を定義できます。検索式は、単一の単語、単一の語句、またはかっこで囲まれた複雑な式が可能であり、必要に応じてブール演算子も使用できます 例として、次のようなものがあります。

  • genre:jazz NOT history

  • artists:("Miles Davis" "John Coltrane")

複数の文字列を 1 つのエンティティとして評価する場合は、必ず両方の文字列を引用符で囲んでください。この場合は、artists フィールドで 2 人の異なるアーティストを検索します。

fieldName:searchExpression に指定されるフィールドは、searchable フィールドでなければなりません。 フィールド定義におけるインデックス属性の利用方法の詳細については、「インデックスの作成」を参照してください。

Note

各フィールド検索式にはフィールド名が明示的に指定されるため、フィールド検索式を使用する際は searchFields パラメーターを使用する必要はありません。 ただし、いくつかの部分で特定のフィールドをスコープにし、他の部分は複数のフィールドに適用できるクエリを実行する場合は、searchFields パラメーターを引き続き使用できます。 たとえば、クエリ search=genre:jazz NOT history&searchFields=description は、genre フィールドの jazz のみと一致し、description フィールドの NOT history と一致します。 fieldName:searchExpression に指定されたフィールド名は常に searchFields パラメーターに優先するため、この例では searchFields パラメーターに genre を含める必要はありません。

あいまい検索

あいまい検索を使用すると、2 つ以下の距離条件を満たす用語を最大 50 の用語まで拡張して、似た構造を持つ用語の一致を見つけることができます。 詳細については、あいまい検索に関するページを参照してください。

あいまい検索を実行するには、1 つの単語の終わりにチルダ記号 ~ を使用し、編集距離を指定する任意のパラメーターである 0 から 2 (既定値) の値を指定します。 たとえば、blue~ または blue~1bluebluesglue を返します。

あいまい検索を適用できるのは用語だけであり、引用符で囲まれた語句には適用できませんが、複数の部分から成る名前または語句の各用語に個別にチルダを追加できます。 たとえば、Unviersty~ of~ Wshington~University of Washington で一致します。

近接検索

近接検索は、ある文書で互いに近くにある言葉を検索します。 語句の終わりにチルダ記号 ~ を挿入し、近接境界となる語数を続けます。 たとえば、"hotel airport"~5 では、ドキュメント内で互いに 5 語以内にある hotelairport という用語が検索されます。

用語ブースト

用語ブーストとは、ブーストされる用語を含むドキュメントに、それを含まないドキュメントより高い順位を付けることです。 これはスコアリング プロファイルとは違います。スコアリング プロファイルは、特定の用語ではなく、特定のフィールドをブーストします。

次の例はその違いを示しています。 特定のフィールドの一致をブーストするスコアリング プロファイルがあるとします。たとえば、musicstoreindex の例genre です。 用語ブーストでは、特定の用語に他の用語より高い順位を与えます。 たとえば、rock^2 electronic を指定すると、genre フィールドに検索用語を含むドキュメントに、インデックスの他の検索可能フィールドより高い順位が与えられます。 さらに、用語のブースト値 (2) の結果、rock という検索用語を含むドキュメントには、electronic というもう 1 つの用語よりも高い順位が与えられます。

用語をブーストするには、キャレット記号 ^ とブースト係数 (数字) を、検索する用語の終わりに使用します。 語句をブーストすることもできます。 ブースト係数が高ければ高いほど、その語句の関連性が他の検索語句に比べて大きくなります。 既定では、増強係数は 1 です。 ブースト係数は正数にする必要がありますが、1 未満 (0.20 など) の数字にすることができます。

正規表現検索

正規表現検索では、RegExp クラスに関するページで説明されているように、Apache Lucene で有効なパターンに基づいて一致が検出されます。 Azure AI Search では、正規表現はスラッシュ / で囲まれます。

たとえば、motel または hotel を含むドキュメントを検索するには、/[mh]otel/ を指定します。 正規表現検索では、単一の単語に対して照合が行われます。

一部のツールと言語では、Azure AI Search によって課されるエスケープ ルールを超えて追加のエスケープ文字の要件が課されます。 JSON の場合、スラッシュを含む文字列は、バック スラッシュでエスケープされます。たとえば microsoft.com/azure/ は、search=/.*microsoft.com\/azure\/.*/ になります。この場合、正規の式を設定するのは search=/.* <string-placeholder>.*/ で、microsoft.com\/azure\/ はエスケープされたスラッシュを含む文字列です。

正規表現クエリの 2 つの一般的な記号は、.* です。 . は任意の 1 文字に一致し、* は前の文字に 0 回以上一致します。 たとえば、/be./beebet という用語に一致しますが、/be*/bebeebeee に一致しますが、bet には一致しません。 組み合わせると、.* は任意の一連の文字を一致させることができるので、/be.*/better などの be で始まる用語に一致します。

正規表現で構文エラーが発生した場合、特殊文字のエスケープ ルールを確認してください。 別のクライアントを試して、問題がツール固有であるかどうかを確認することもできます。

ワイルドカード検索

複数 (*) または単数 (?) の文字のワイルドカード検索で、一般に認識されている構文を使用できます。 完全な Lucene 構文では、プレフィックス、挿入辞、およびサフィックスの一致がサポートされています。

Lucene Query Parser では、これらの文字を語句ではなく 1 つの用語に利用することにご注意ください。

接辞型 説明と例
prefix 用語の断片が * または ? の前にあります。 たとえば、search=alpha* のクエリ式では、alphanumeric または alphabetical が返されます。 プレフィックス一致は、シンプルな構文と完全な構文の両方でサポートされています。
敬称 用語の断片が * または ? の後にあります。スラッシュを使用してコンストラクトを区切ります。 たとえば、search=/.*numeric/ では alphanumeric が返されます。
挿入辞 用語の断片が * または ? を囲みます。 たとえば、search=non*al では non-numericalnonsensical が返されます。

演算子をひとつの式に結合できます。 たとえば、980?2*98072-122298052-1234 に一致します。ここで、? が 1 つの (必須) 文字に一致し、* がその後に続く任意の長さの文字に一致します。

サフィックスの一致には、正規表現のスラッシュ / 区切り記号が必要です。 一般に、/ なしで、用語の最初の文字として * または ? 記号を使用することはできません。 また、* は正規表現クエリ以外で使用すると動作が異なる点に注意することも重要です。 正規表現のスラッシュ / 区切り記号を別とすれば、* はワイルドカード文字であり、正規表現での .* とほぼ同じように任意の一連の文字に一致します。 たとえば、search=/non.*al/ では search=non*al と 同じ結果セットが生成されます。

Note

原則として、パターン マッチングは低速であるため、用語内の文字シーケンスのトークンを作成するエッジ n-gram トークン化など、別の方法を検討することもできます。 n-gram トークン化では、インデックスのサイズは大きくなりますが、パターンの構成やインデックスを付ける文字列の長さによっては、クエリの実行速度が速くなる場合があります。 詳細については、「部分的な用語検索と特殊文字を含むパターン」をご覧ください。

ワイルドカード クエリに対するアナライザーの影響

クエリの解析中には、プレフィックス、サフィックス、ワイルドカードとして定式化されたクエリ、または正規の式は、語彙分析をバイパスして、クエリ ツリーにそのまま渡されます。 クエリで指定した形式の文字列がインデックスに含まれている場合に限って、一致が検出されます。 部分一致やパターン一致をうまく検出するためには、ほとんどの場合、文字列の整合性を維持するインデックスの作成時にアナライザーが必要になります。 詳細については、「Azure AI Search クエリでの部分一致検索」を参照してください。

terminal* という検索クエリで terminateterminationterminates などの用語を含む結果を返す状況を考えてください。

en.lucene (English Lucene) アナライザーを使用する場合、各用語の語幹処理が積極的に適用されます。 たとえば、terminateterminationterminates はすべて、インデックスではトークン termi にトークン化されます。 一方、ワイルドカードやあいまい検索を使用するクエリの用語はまったく分析されません。そのため、terminat* クエリに一致する結果はありません。

一方、Microsoft analyzers (この場合、en.microsoft アナライザー) はもう少し高度であり、語幹処理の代わりに見出し語選定が使用されます。 つまり、生成されたトークンはすべて正しい英単語になります。 たとえば、terminateterminatestermination はほとんどの場合、インデックスに全体として残り、ワイルドカードやあいまい検索に多く依存するシナリオに最適です。

ワイルドカード クエリと正規表現クエリのスコアリング

Azure AI Search では、テキスト クエリに、頻度に基づいたスコアリング (BM25) を使用します。 ただし、用語のスコープが広くなる可能性があるワイルドカード クエリと正規表現クエリでは、出現頻度が低い用語の一致に対する優先度付けに偏りが発生するのを避けるために、頻度の係数は無視されます。 すべての一致は、ワイルドカード検索と正規表現検索で同等に扱われます。

特殊文字

場合によっては、"❤" のような絵文字や "€" のような記号などの特殊文字を検索することが必要です。 そのような場合は、使用しているアナライザーによってそれらの文字が除外されないことを確認します。標準アナライザーでは多くの特殊文字が無視され、インデックスから除外されます。

特殊文字をトークン化するアナライザーには、whitespace アナライザーが含まれ、ここでは、空白で区切られた任意の文字シーケンスがトークンとして考慮されます (したがって という文字列はトークンと見なされます)。 また、Microsoft English アナライザー ("en.microsoft") のような言語アナライザーでは、"€" という文字列がトークンとして見なされます。 アナライザーをテストして、特定のクエリに対して生成されるトークンを確認できます。

Unicode 文字を使用する場合は、クエリ URL でシンボルが適切にエスケープされていることを確認します (たとえば、 の場合は、エスケープ シーケンス %E2%9D%A4+ を使用します)。 一部の REST クライアントでは、この変換が自動的に行われます。

優先順位 (グループ化)

かっこを使用して、かっこで囲まれたステートメント内に演算子を含むサブクエリを作成できます。 たとえば、motel+(wifi|luxury) では、motel という用語と wifi または luxury (あるいはその両方) を含むドキュメントが検索されます。

フィールドのグループ化は似ていますが、グループ化のスコープを 1 つのフィールドに設定します。 たとえば、hotelAmenities:(gym+(wifi|pool)) では、hotelAmenities のフィールドで gymwifi、または gympool が検索されます。

クエリ サイズの上限

Azure AI Search では、無制限のクエリによって検索サービスが不安定になるおそれがあるため、クエリのサイズと構成に制限が適用されます。 クエリのサイズと構成 (句の数) には制限があります。 制限は、プレフィックス検索の長さと、正規表現検索およびワイルドカード検索の複雑さにもあります。 アプリケーションがプログラムで検索クエリを生成する場合は、無制限のサイズのクエリが生成されないように設計することをお勧めします。

クエリの制限の詳細については、「API 要求の制限」を参照してください。

関連項目