標準クエリパーサー

Solrのデフォルトのクエリパーサーは、「lucene」パーサーとしても知られています。

標準クエリパーサーの主な利点は、堅牢で直感的な構文をサポートし、さまざまな構造化クエリを作成できることです。最大の欠点は、DisMaxクエリパーサーのように、できるだけエラーを少なくするように設計されているものと比較して、構文エラーに非常に非寛容であることです。

標準クエリパーサーパラメータ

一般的なクエリパラメータファセッティングパラメータ、ハイライト表示パラメータ、およびMoreLikeThisパラメータに加えて、標準クエリパーサーは下記の表に記載されているパラメータをサポートしています。

q

標準クエリ構文を使用してクエリを定義します。このパラメータは必須です。

q.op

クエリ式のデフォルト演算子を指定します。「AND」または「OR」が可能です。

df

デフォルトの検索可能なフィールドを指定します。

sow

空白で分割します。trueに設定されている場合、テキスト分析は個々の空白で区切られた各用語に対して個別に呼び出されます。デフォルトはfalseです。空白で区切られた用語シーケンスは、一度にテキスト分析に提供され、用語シーケンスに対して動作する分析フィルタ(例:複数単語の同義語やシングル)の適切な機能が有効になります。

デフォルトのパラメータ値はsolrconfig.xmlで指定するか、リクエスト内のクエリ時値でオーバーライドします。

標準クエリパーサーのレスポンス

デフォルトでは、標準クエリパーサーからのレスポンスには、名前のない1つの<result>ブロックが含まれています。debugパラメータが使用されている場合、「debug」という名前の追加の<lst>ブロックが返されます。これには、元のクエリ文字列、解析されたクエリ文字列、および<result>ブロック内の各ドキュメントの説明情報など、便利なデバッグ情報が含まれています。explainOtherパラメータも使用されている場合、そのクエリに一致するすべてのドキュメントに関する追加の説明情報が提供されます。

サンプルレスポンス

このセクションでは、標準クエリパーサーからのレスポンスの例を示します。

以下のURLは、単純なクエリを送信し、XMLレスポンスライターにインデントを使用してXMLレスポンスを読みやすくするように要求します。

https://127.0.0.1:8983/solr/techproducts/select?q=id:SP2514N&wt=xml

結果

<response>
<responseHeader><status>0</status><QTime>1</QTime></responseHeader>
<result numFound="1" start="0">
 <doc>
  <arr name="cat"><str>electronics</str><str>hard drive</str></arr>
  <arr name="features"><str>7200RPM, 8MB cache, IDE Ultra ATA-133</str>
    <str>NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor</str></arr>
  <str name="id">SP2514N</str>
  <bool name="inStock">true</bool>
  <str name="manu">Samsung Electronics Co. Ltd.</str>
  <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
  <int name="popularity">6</int>
  <float name="price">92.0</float>
  <str name="sku">SP2514N</str>
 </doc>
</result>
</response>

以下は、フィールドリストが制限されたクエリの例です。

https://127.0.0.1:8983/solr/techproducts/select?q=id:SP2514N&fl=id+name&wt=xml

結果

<response>
<responseHeader><status>0</status><QTime>2</QTime></responseHeader>
<result numFound="1" start="0">
 <doc>
  <str name="id">SP2514N</str>
  <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
 </doc>
</result>
</response>

標準クエリパーサーの用語の指定

標準クエリパーサーへのクエリは、用語と演算子に分割されます。用語には、単一用語と句の2つの種類があります。

  • 単一用語は、「test」や「hello」などの単一の単語です。

  • 句は、「hello dolly」など、二重引用符で囲まれた単語のグループです。

複数の用語をブール演算子で組み合わせて、より複雑なクエリを作成できます(下記参照)。

クエリに使用されるアナライザが、インデックスに使用されるアナライザと同様の方法で用語と句を解析することが重要です。そうでなければ、検索は予期せぬ結果を生成する可能性があります。

用語修飾子

Solrは、必要に応じて検索に柔軟性または精度を追加する様々な用語修飾子をサポートしています。これらの修飾子には、ワイルドカード文字、検索を「あいまい」またはより一般的にするための文字などが含まれます。以下のセクションでは、これらの修飾子について詳しく説明します。

ワイルドカード検索

Solrの標準クエリパーサは、単一用語内の単一文字および複数文字のワイルドカード検索をサポートしています。ワイルドカード文字は単一用語に適用できますが、検索句には適用できません。

ワイルドカード検索の種類 特殊文字

単一文字(1文字に一致)

?

検索文字列te?tは、testとtextの両方に一致します。

複数文字(0個以上の連続する文字に一致)

*

ワイルドカード検索:tes*は、test、testing、testerに一致します。用語の中央にもワイルドカード文字を使用できます。例えば:te*tはtestとtextに一致します。*estはpestとtestに一致します。

あいまい検索

Solrの標準クエリパーサは、Damerau-Levenshtein距離または編集距離アルゴリズムに基づいたあいまい検索をサポートしています。あいまい検索では、必ずしも完全一致ではない、指定された用語と類似した用語が検出されます。あいまい検索を実行するには、単一単語の用語の最後にチルダ記号~を使用します。たとえば、「roam」とスペルが似た用語を検索するには、次のあいまい検索を使用します。

roam~

この検索は、roams、foam、foamsなどの用語に一致します。「roam」自体にも一致します。

オプションの距離パラメータは、許可される最大編集数を0〜2で指定し、デフォルトは2です。例えば

roam~1

これはroamsとfoamに一致しますが、編集距離が「2」であるfoamsには一致しません。

多くの場合、ステミング(用語を共通の語幹に削減すること)は、あいまい検索やワイルドカード検索と同様の効果を生み出すことができます。

近接検索

近接検索では、互いに特定の距離内にある用語を探します。

近接検索を実行するには、チルダ文字~と数値を検索句の最後に追加します。たとえば、ドキュメント内で互いに10単語以内に「apache」と「jakarta」を検索するには、次の検索を使用します。

"jakarta apache"~10

ここで言及されている距離は、指定された句に一致させるために必要な用語の移動回数です。上記の例では、「apache」と「jakarta」がフィールド内で10スペース離れていても、「apache」が「jakarta」の前に表示される場合、「apache」を「jakarta」の右側にスペースを挟んで配置するために、10回以上の用語移動が必要になります。

存在検索

フィールドの存在検索は、そのフィールドに値が存在するすべてのドキュメントに一致します。フィールドの存在を照会するには、検索で用語の代わりにワイルドカードを使用するだけです。

field:*

値がある場合、多くの場合「存在しない」と見なされる値(例:NaN""など)であっても、フィールドは「存在する」と見なされます。

範囲検索

範囲検索は、フィールドの値の範囲(上限と下限のある範囲)を指定します。クエリは、指定されたフィールドの値がその範囲内にあるドキュメントに一致します。範囲クエリは、上限と下限を含む場合と含まない場合があります。数値フィールドを除き、ソートは辞書式に行われます。たとえば、以下の範囲クエリは、popularityフィールドの値が52から10,000の間(両端を含む)にあるすべてのドキュメントに一致します。

popularity:[52 TO 10000]

範囲クエリは、日付フィールドや数値フィールドのみに限定されません。日付以外のフィールドでも範囲クエリを使用できます。

title:{Aida TO Carmen}

これにより、タイトルがAidaとCarmenの間にあるすべてのドキュメントが見つかりますが、AidaとCarmen自体は含まれません。

クエリの周りの括弧は、その包含性を決定します。

  • 角括弧[]は、上限と下限を含む値に一致する包含範囲クエリを示します。

  • 波括弧{}は、上限と下限の間の値に一致する排他的範囲クエリを示しますが、上限と下限自体は除外されます。

  • これらの種類を組み合わせることで、範囲の一方の端を包含的に、もう一方の端を排他的にすることができます。例:count:{1 TO 10]

ワイルドカード*も、どちらか一方または両方の端点に使用して、開いた範囲クエリを指定できます。これはLuceneのクラシッククエリパーサからのずれです。

  • field:[* TO 100]は、100以下のすべてのフィールド値を見つけます。

  • field:[100 TO *]は、100以上のすべてのフィールド値を見つけます。

  • field:[* TO *]は、そのフィールドタイプについて-Infinityと+Infinityの実効値の間の値を持つドキュメントを見つけます。

ワイルドカードによるNaN値の一致

ほとんどのフィールドでは、無制限の範囲クエリfield:[* TO *]は存在クエリfield: *と同等です。ただし、NaN値をサポートするfloat/doubleタイプの場合、これらの2つのクエリは異なる動作をします。

  • field:*は、NaNを含むすべての既存の値に一致します。

  • field:[* TO *]は、NaNを除くすべての実数値に一致します。

"^"を使用した用語のブースト

Solrは、検出された用語に基づいて、一致するドキュメントの関連性のレベルを提供します。用語をブーストするには、キャレット記号^とブースト係数(数値)を検索する用語の最後に使用します。ブースト係数が高いほど、その用語はより関連性が高くなります。

ブーストを使用すると、用語をブーストすることでドキュメントの関連性を制御できます。たとえば、

"jakarta apache"を検索していて、「jakarta」という用語をより関連性の高いものにする場合は、用語の直後に^記号とブースト係数を追加することでブーストできます。たとえば、次のように入力できます。

jakarta^4 apache

これにより、「jakarta」という用語を含むドキュメントがより関連性の高いものとして表示されます。次の例のように、句用語もブーストできます。

"jakarta apache"^4 "Apache Lucene"

デフォルトでは、ブースト係数は1です。ブースト係数は正でなければなりませんが、1未満にすることもできます(たとえば、0.2にすることもできます)。

"^="による定数スコア

定数スコアクエリは<query_clause>^=<score>で作成され、その句に一致するドキュメントすべてについて、句全体を指定されたスコアに設定します。これは、特定の句の一致のみを気にし、用語頻度(フィールドに出現する用語の数)や逆ドキュメント頻度(フィールド内で用語がどれだけまれであるかを全体のインデックスで測定する尺度)などの他の関連性の要因を考慮したくない場合に望ましいものです。

(description:blue OR color:blue)^=1.0 text:shoes

特定のフィールドの照会

Solrにインデックスされたデータは、スキーマで定義されたフィールドに編成されています。検索では、フィールドを利用してクエリの精度を高めることができます。たとえば、特定のフィールド(タイトルフィールドなど)内でのみ用語を検索できます。

スキーマは、1つのフィールドをデフォルトフィールドとして定義します。クエリでフィールドを指定しない場合、Solrはデフォルトフィールドのみを検索します。または、クエリで別のフィールドまたはフィールドの組み合わせを指定することもできます。

フィールドを指定するには、フィールド名にコロン「:」、次にそのフィールド内で検索する用語を入力します。

たとえば、インデックスにtitleとtextの2つのフィールドが含まれており、textがデフォルトフィールドであるとします。「don’t go this way」というテキストを含む「The Right Way」というドキュメントを見つけたい場合、検索クエリに次のいずれかの用語を含めることができます。

title:"The Right Way" AND text:go

title:"Do it right" AND go

textはデフォルトフィールドであるため、フィールドインジケータは必要ありません。したがって、上記の2番目のクエリではそれを省略しています。

フィールドは、その直前にある用語に対してのみ有効であるため、クエリtitle:Do it rightはタイトルフィールドの「Do」のみを見つけます。「it」と「right」はデフォルトフィールド(この場合はテキストフィールド)で見つかります。

標準クエリパーサでサポートされているブール演算子

ブール演算子を使用すると、ブール論理をクエリに適用し、ドキュメントに一致させるために、フィールド内の特定の用語または条件の存在または非存在を要求できます。以下の表は、標準クエリパーサでサポートされているブール演算子をまとめたものです。

ブール演算子 代替記号 説明

AND

&&

ブール演算子の両側の用語の両方が存在している場合に一致する必要があります。

NOT

!

次の用語が存在しない必要があることを示します。

OR

||

どちらかの用語(または両方の用語)が存在している場合に一致する必要があります。

+

次の用語が存在する必要があることを示します。

-

次の用語を禁止します(つまり、その用語を含まないフィールドまたはドキュメントに一致します)。-演算子は、ブール演算子!と機能的に似ています。Googleなどの一般的な検索エンジンで使用されているため、一部のユーザーコミュニティにはより馴染みがあるかもしれません。

ブール演算子を使用すると、論理演算子を使用して用語を組み合わせることができます。Luceneは、AND、「+」、OR、NOT、「-」をブール演算子としてサポートしています。

ANDやNOTなどのキーワードでブール演算子を指定する場合、キーワードはすべて大文字で表示する必要があります。
標準クエリパーサは、上記の表にリストされているすべてのブール演算子をサポートしています。DisMaxクエリパーサは+-のみをサポートしています。

OR演算子は、デフォルトの接続演算子です。つまり、2つの用語の間にブール演算子が存在しない場合、OR演算子が使用されます。OR演算子は2つの用語をリンクし、どちらかの用語がドキュメントに存在する場合に一致するドキュメントを見つけます。これは、集合を使用する和集合と同等です。記号||をORの代わりに使用できます。

"jakarta apache"または"jakarta"のみを含むドキュメントを検索するには、次のクエリを使用します。

"jakarta apache" jakarta

または

"jakarta apache" OR jakarta

ブール演算子"+"

+記号(「必須」演算子とも呼ばれる)は、クエリが一致を返すために、フィールドのどこかに少なくとも1つのドキュメントで+記号の後の用語が存在する必要があることを示します。

たとえば、「jakarta」を含んでいて、「lucene」を含んでいてもいなくてもよいドキュメントを検索するには、次のクエリを使用します。

+jakarta lucene

この演算子は、標準クエリパーサとDisMaxクエリパーサの両方でサポートされています。

ブール演算子AND ("&&")

AND演算子は、両方の用語が単一ドキュメントのテキスト内のどこにでも存在するドキュメントに一致します。これは、集合を使用する積集合と同等です。記号&&をANDの代わりに使用できます。

"jakarta apache"と"Apache Lucene"を含むドキュメントを検索するには、次のいずれかのクエリを使用します。

"jakarta apache" AND "Apache Lucene"

"jakarta apache" && "Apache Lucene"

ブール演算子NOT ("!")

NOT演算子は、NOTの後の用語を含むドキュメントを除外します。これは、集合を使用する差集合と同等です。記号!をNOTの代わりに使用できます。

次のクエリは、「jakarta apache」という句を含むが、「Apache Lucene」という句を含まないドキュメントを検索します。

"jakarta apache" NOT "Apache Lucene"

"jakarta apache" ! "Apache Lucene"

ブール演算子"-"

-記号または「禁止」演算子は、-記号の後の用語を含むドキュメントを除外します。

たとえば、「jakarta apache」を含むが「Apache Lucene」を含まないドキュメントを検索するには、次のクエリを使用します。

"jakarta apache" -"Apache Lucene"

特殊文字のエスケープ

Solrは、クエリに以下の特殊文字が現れた場合、それらに特別な意味を与えます。

+ - && || ! ( ) { } [ ] ^ " ~ * ? : /

これらの文字を特殊文字としてではなく、文字通りに解釈させるには、文字の前にバックスラッシュ文字 `\` を付けます。例えば、(1+1):2 を検索する場合、Solrがプラス記号と括弧を2つの項を持つサブクエリの作成のための特殊文字として解釈しないようにするには、それぞれの文字の前にバックスラッシュを付けてエスケープします。

\(1\+1\)\:2

サブクエリを形成するための項のグループ化

Solrは、句をグループ化してサブクエリを形成するために括弧を使用することをサポートしています。これは、クエリのブール論理を制御したい場合に非常に役立ちます。

以下のクエリは、「jakarta」または「apache」と「website」のいずれかを検索します。

(jakarta OR apache) AND website

これはクエリに精度を追加し、「website」という語句と、「jakarta」と「apache」のいずれかの語句が存在する必要があることを要求します。

フィールド内の句のグループ化

検索内の単一フィールドに2つ以上のブール演算子を適用するには、ブール句を括弧でグループ化します。例えば、以下のクエリは、「return」という単語と「pink panther」という句の両方をタイトルフィールドに含むものを検索します。

title:(+return +"pink panther")

クエリ内のコメント

Cスタイルのコメントはクエリ文字列でサポートされています。

"jakarta apache" /* これは通常のクエリ文字列の中間にあるコメントです */ OR jakarta

コメントはネストできます。

Luceneの従来のクエリパーサーとSolrの標準クエリパーサーの違い

Solrの標準クエリパーサーは、Luceneの「従来の」QueryParserのバリエーションとして生まれました。以下の点で異なります。

  • `*` は、開いた範囲クエリを指定するために、どちらか一方または両方の端点に使用するか、存在クエリとして単独で使用できます。

    • `field:[* TO 100]` は、100以下のすべてのフィールド値を見つけます。

    • `field:[100 TO *]` は、100以上のすべてのフィールド値を見つけます。

    • `field:[* TO *]` は、フィールドに値を持つ(`-Infinity`と`Infinity`の間、`NaN`を除く)すべてのドキュメントを見つけます。

    • `field:*` は、フィールドが存在する(つまり、任意の値を持つ)すべてのドキュメントを見つけます。

  • 純粋な否定クエリ(すべての句が禁止されている)が許可されます(最上位句としてのみ)。

    • `-inStock:false` は、inStockがfalseではないすべてのフィールド値を見つけます。

    • `-field:*` は、フィールドに値を持たないすべてのドキュメントを見つけます。

  • ローカルパラメータ構文を使用して、ネストされた句として任意の種類のクエリパーサーを使用した埋め込みSolrクエリ(サブクエリ)のサポート。

    • inStock:true OR {!dismax qf='name manu' v='ipod'}

      注意点:クエリの先頭に`{!`で開始しないように注意してください。これは、クエリの文字列全体の解析を変更し、追加の句がある場合は意図したとおりに動作しない可能性があります。そのため、上記の例を反転してサブクエリを最初にすると、先頭にスペースがないと期待通りに動作しません。

      サブクエリは、マジックフィールド`_query_`を使用して行うこともできます。関数クエリの場合はマジックフィールド`_val_`を使用できますが、分かりにくいので非推奨とすべきです。例:`_val_:"recip(rord(myfield),1,2,3)"`

  • いくつかのクエリ句をフィルタキャッシュ(定数スコアのブールクエリとして)にキャッシュする必要があることを示す特別な`filter(…​)`構文のサポート。これにより、サブクエリをキャッシュして他のクエリで再利用できます。例えば`inStock:true`は、以下の3つのクエリのすべてでキャッシュされ、再利用されます。

    • q=features:songs OR filter(inStock:true)

    • q=+manu:Apple +filter(inStock:true)

    • q=+manu:Apple & fq=inStock:true

      これは、複雑なフィルタクエリの個々の句をキャッシュするためにも使用できます。以下の最初のクエリでは、3つの項目がフィルタキャッシュに追加され(最上位の`fq`と両方の`filter(…​)`句)、2番目のクエリでは、2回のキャッシュヒットと1回の新しいキャッシュ挿入(新しい最上位の`fq`用)があります。

    • q=features:songs & fq=+filter(inStock:true) +filter(price:[* TO 100])

    • q=manu:Apple & fq=-filter(inStock:true) -filter(price:[* TO 100])

  • 範囲クエリ("[a TO z]")、プレフィックスクエリ("a*")、およびワイルドカードクエリ("a*b")は、定数スコアリングです(一致するすべてのドキュメントに同じスコアが付けられます)。スコアリング要因TF、IDF、インデックスブースト、および"coord"は使用されません。一致する用語の数に制限はありません(Luceneの以前のバージョンでは制限がありました)。

  • 定数スコアのクエリは`<query_clause>^=<score>`で作成され、これにより、その句に一致するドキュメントの句全体が指定されたスコアに設定されます。

    • q=(description:blue color:blue)^=1.0 title:blue^=5.0

日付と時刻の指定

日付ベースのフィールドに対するクエリでは、適切な日付フォーマットを使用する必要があります。正確な日付値のクエリには、`:`がフィールドクエリを示すパーサー構文であるため、引用符またはエスケープが必要です。

  • createdate:1976-03-06T23\:59\:59.999Z

  • createdate:"1976-03-06T23:59:59.999Z"

  • createdate:[1976-03-06T23:59:59.999Z TO *]

  • createdate:[1995-12-31T23:59:59.999Z TO 2007-03-06T00:00:00Z]

  • timestamp:[* TO NOW]

  • pubdate:[NOW-1YEAR/DAY TO NOW/DAY+1DAY]

  • createdate:[1976-03-06T23:59:59.999Z TO 1976-03-06T23:59:59.999Z+1YEAR]

  • createdate:[1976-03-06T23:59:59.999Z/YEAR TO 1976-03-06T23:59:59.999Z]