クエリ文字列

クエリ文字列は Unicode 文字で記述します。クエリ文字列の最大文字数は 2,000 文字です。クエリ文字列にはいずれにもフィールド値を少なくとも 1 つ含めます。Atom フィールド、テキスト フィールド、HTML フィールドの検索では大文字と小文字は区別されないため、フィールド値は小文字で記述することをおすすめします。また、クエリ文字列ではブール演算子 ANDORNOT も使用できますが、大文字で記述することで認識されます。

クエリ文字列でカンマを使用できるのは、関数 distance(home, geopoint(35.2, 40.5)) > 100 の引数の区切り文字として使用する場合と、引用符で囲んだ文字列の中で使用する場合のみです。

クエリ文字列はさまざまな形式で記述できます。クエリを作成する方法は、フィールド名を含めるか含めないかで大きく 2 つに分けられます。グローバル検索では、フィールド値のみを記述したクエリ文字列を使用します。

String query = "blue";
String query = "NOT white";
String query = "blue OR red";
String query = "blue guitar";

フィールド検索では、フィールド名とフィールド値を指定する 1 つ以上の式を記述したクエリ文字列を使用します。

String query = "model:gibson date < 1965-01-01";
String query = "title:\"Harry Potter\" AND pages<500";
String query = "beverage:wine color:(red OR white) NOT country:france";

このドキュメントでは、グローバル検索とフィールド検索で使用するクエリ文字列の作成方法を説明します。また、それぞれの検索で使用されるロジックについても説明します。

実行されたクエリの記録を保持する場合は、アプリケーションでクエリ文字列をログに記録することをおすすめします。

グローバル検索では、値を指定して、その値がいずれかのドキュメント フィールドに含まれるドキュメントを検索できます。グローバル検索を実行するには、1 つ以上のフィールド値を含むクエリ文字列を記述します。検索アルゴリズムに従ってそれぞれの値のタイプが判別され、その値を含む可能性があるすべてのドキュメント フィールドが検索されます。

単一値のクエリ

単一値のクエリ文字列による検索は次のルールに従って処理されます。

クエリ文字列が単語(red)または引用符付き文字列("red rose")の場合、インデックス内の以下のすべてのドキュメントが検索されます。

  • 指定の単語または引用符付き文字列を含むテキスト フィールドまたは HTML フィールド(大文字と小文字は区別されない)。
  • 単語または引用符付き文字列に一致する値を含む Atom フィールド(大文字と小文字は区別されない)。

クエリ文字列が数値(3.14159)の場合、次のフィールドを含むすべてのドキュメントが取得されます。

  • クエリで指定された数値に一致するトークンを含むテキスト フィールドまたは HTML フィールド(「he took 5 minutes」というテキスト フィールドは、クエリの数値が 5 であれば一致するが 5.0 では一致しない)。
  • クエリで指定された数値のテキストに文字どおり一致する Atom フィールド。

クエリ文字列が日付(形式は yyyy-mm-dd)の場合、次のフィールドを含むすべてのドキュメントが取得されます。

  • クエリで指定された日付と等しい値を含む日付フィールド(クエリ文字列では先頭のゼロは省略可能で、「2012-07-04」と「2012-7-4」は同じ日付と解釈される)。
  • クエリで指定された日付のテキストに文字どおり一致するトークンを含むテキスト フィールドまたは HTML フィールド。
  • クエリで指定された日付のテキストに文字どおり一致する Atom フィールド。

単語 1 つのクエリでは、単語の前にブール演算子 NOT(大文字)を指定できます。この演算子を指定すると、同じルールに従って値が照合され、クエリの値に一致するフィールドがないドキュメントのリストが返されます。たとえば、「NOT red」というクエリでは、「red」を含むテキスト フィールドと HTML フィールドがなく、値が「red」である Atom フィールドがないドキュメントがすべて取得されます。

上記には地理的位置フィールドの説明がありませんが、現在のところ、地理的位置を示す生の値を文字列として指定することはできないため、地理的位置をグローバル検索で検索することはできません。

複数値のクエリ

グローバル検索の文字列では、複数の値をスペースで区切って指定できます。単語、引用符付き文字列、数値、日付を区切る空白文字は暗黙的に AND 演算子として扱われます。以下の 2 つの検索文字列は、グローバル検索における Atom フィールドの処理方法の違い(後述)を除き、ほぼ同じように処理されます。

query = "small red"
query = "small AND red"

複数値のグローバル検索を実行するときは、以下のルールに従って、文字列に含まれる各値についてフィールドの照合が個別に行われます。Atom フィールドの照合の扱いが異なる点に注意してください。

  • テキスト フィールドまたは HTML フィールドではクエリの値が順序に関係なく照合される。
  • それぞれの値が異なるフィールドにあっても照合される。
  • Atom フィールドはクエリ文字列にブール演算子(ANDORNOT)が含まれていない場合にのみ検索され、値がクエリ文字列全体と同じ場合にのみ一致と見なされる。

3 番目の Atom フィールドに関するルールに注意が必要です。たとえば、「red small」というクエリ文字列にはブール演算子 AND がないため(暗黙的には同じ)、一致する Atom フィールドの検索が試行されます。一方、「red AND small」という文字列にはブール演算子が含まれているため、このクエリ文字列では Atom フィールドの照合は試行されません。

次の例は、「rose bud」というクエリ文字列で取得された 4 つのドキュメントを示したものです。各ドキュメントに 2 つのテキスト フィールドと 1 つの Atom フィールドがあります。各ドキュメントについて、クエリを満たすと見なされる理由をコメント欄に示してあります。

ドキュメント ID テキスト フィールド 1 テキスト フィールド 2 Atom フィールド コメント
1 mighty like a rose one bud to bind them all thorn bush 一致する値が異なるフィールドにあっても照合される。
2 wide like a river like a bud on a rose tumble weed 一致する値が同じテキスト フィールドまたは HTML フィールドにあれば、間に他のテキストがあっても、順序に関係なく照合される。
3 deep like the ocean the rose bud boys blue bonnet 一致する値が同じテキスト フィールドまたは HTML フィールドにあれば、順序に関係なく照合される。
4 tall like a mountain the beautiful garden rose bud Atom フィールドの値がクエリ文字列全体と同じであれば一致と見なされる。

このクエリの値の順序を逆にして「bud rose」を検索した場合、ドキュメント 1、2、3 は返されますが、ドキュメント 4 は返されなくなります。Atom フィールド、テキスト フィールド、HTML フィールドで完全に一致する文字列を検索するには、その文字列を引用符で囲んだクエリ文字列を使用します。"rose bud" を検索するとドキュメント 3 と 4 だけが返されます。

ブール演算子

ブール演算子を使用してより複雑なグローバル検索を指定できます。NOT は値の前、AND と OR は値の間に記述します。これらの演算子は大文字で記述する必要があるので注意してください。引用符で囲まれた文字列の中に含まれている場合は、演算子としてではなく、フィールド値の一部として扱われます。クエリ文字列で括弧を使用するとロジックを明確に記述できます。

ブール演算子は、NOTORAND の順に解釈されます。

NOT cat AND dogs OR horses --> (NOT cat) AND (dogs OR horses)
NOT cat OR dogs AND horses --> ((NOT cat) OR dogs) AND horses

ステミング

複数形や動詞の活用形など、単語の一般的な変化形を検索するには、~ ステミング演算子(チルダ文字)を使用します。このプレフィックス演算子は、値の前にスペースで区切らずに入力する必要があります。値 ~cat は「cat」や「cats」に一致し、同様に値 ~dog は「dog」や「dogs」に一致します。ステミング アルゴリズムは完全ではありません。たとえば、値 ~care は「care」と「caring」には一致しますが、「cares」や「cared」には一致しません。ステミングは、テキスト フィールドと HTML フィールドの検索でのみ使用されます。

トークン化

ドキュメントをインデックスに登録すると、そのフィールドがトークン化されます。同様に、クエリ文字列の値もトークン化されます。そのため、単一値のクエリのように見えても、実際は複数値のクエリとして扱われます。例:

"real-time" --> "real time"
"2001-12-15" --> "2001 12 15"
"1.5" --> "1 5"

フィールド検索では、フィールド名を指定して、特定のドキュメント フィールドの値を検索できます。フィールド検索のクエリ文字列は、フィールド名、関係演算子、フィールド値を指定する 1 つ以上の式で構成されます。使用できる関係演算子はフィールドの種類によって異なります。コロンまたは等号で表現される等価演算子は、いずれの種類のフィールドでも使用できます。各種のフィールドに対するクエリ文字列の例を次に示します。

query = "pet = dog"
query = "author = \"Ray Bradbury\""
query = "color:red"
query = "NOT color:red"
query = "price < 500"
query = "birthday>=2011-05-10"

関係演算子の前後の空白文字は省略可能です。グローバル検索のクエリ文字列と同様に、テキスト フィールド、HTML フィールド、Atom フィールドの値を引用符で囲んで文字列を指定できます。また、フィールド値の式の前に大文字で NOT と記述して否定を表現できます。

Atom フィールドのクエリ

Atom フィールドには文字列の値が格納されます。Atom フィールドのクエリでは大文字と小文字は区別されません。クエリ文字列で空白文字や句読点を含むフィールド値を指定する場合は、値を引用符で囲んでください。Atom フィールドで使用できる関係演算子は等価演算子のみです。Atom フィールドの照合では、フィールドの内容全体がクエリの値と同じでないと一致とは見なされません。これには、フィールド内の Unicode の結合文字やアクセント記号付きの文字も含まれます。Atom フィールドではステミングはサポートされません。

クエリ文字列 コメント
"weather=stormy"
"weather: stormy"
どちらの形式の等価演算子も有効です。weather フィールドの値が「stormy」と等しいドキュメントが取得されます。
"Title: \"Tom&Jerry\""
"Couple: \"Fred and Ethel\""
"Version = \"1HCP(21.3)\""
空白文字や特殊文字を含む Atom フィールドを検索する場合は、値を引用符で囲みます。
"Color = (red OR blue)"
"Color = (\"dark red\" OR \"bright blue\")"
括弧と論理演算子 OR を使用して、フィールド値の候補のリストを指定できます。

テキスト フィールドと HTML フィールドのクエリ

テキスト フィールドと HTML フィールドで使用できる関係演算子は等価演算子のみです。この場合の演算子は、「値が等しいフィールド」ではなく、「値を含むフィールド」を意味します。ステミング演算子を使用して単語の変化形を検索できます。また、演算子の OR と AND を使用してフィールド値の複雑なブール式を指定することもできます。引用符で囲まれた文字列の中にブール演算子が含まれている場合は、演算子としてではなく、照合する文字列の一部として扱われます。HTML フィールドの検索では、HTML マークアップ タグ内のテキストは無視されることに注意してください。テキスト フィールドと HTML フィールドのクエリでは大文字と小文字は区別されません。これらのフィールドをインデックスに登録する際、Unicode の結合文字やアクセント記号付きの文字は、アクセント記号なしの対応する文字に正規化されます。これらのフィールドに含まれる結合文字とアクセント記号はクエリ文字列でも正規化されるため、クエリでアクセント記号を指定したかどうかに関係なく、いずれの場合もフィールドの照合が可能です。

クエリ文字列コメント
"Comment = great"
"Comment: great"
どちらの形式の等価演算子も有効です。Comment フィールドに「great」という単語を 1 つでも含むドキュメントが取得されます。
"Comment = (great big ball)"
"Comment = (great AND big AND ball)"
順序に関係なくフィールド内の複数の単語を検索するには、それらの単語を括弧で囲みます。このクエリ文字列では、指定した 3 つの単語すべてを Comment フィールドに含むドキュメントが取得されます。3 つの単語がすべて含まれてさえいれば、その順序や間に他の単語が含まれているかは関係ありません。単語を区切るスペースは暗黙的に論理 AND であると見なされます。2 つ目の形式は、これを明示的に指定したものです。
"Comment = \"insanely great\"" テキストが完全に一致する文字列を検索するには、文字列を引用符で囲みます。このクエリでは、Comment フィールドに「insanely great」というフレーズを含むドキュメントが取得されます(トークン化されると同じになる「insanely-great」も検索されます)。
"pet = ~dog" このステミング演算子では、pet フィールドで「dog」の変化形が照合されます。
"Color = (red OR blue)" 複数の候補のいずれかに一致するものを検索するには、キーワード OR を間に入れて候補のリストを指定し、そのリストを括弧で囲みます。このクエリでは、Color フィールドに「red」と「blue」のいずれかまたは両方を含むドキュメントが取得されます。
"weather = ((rain OR snow) AND cold)" 論理演算子の OR と AND を括弧と組み合わせて、さらに複雑なフィールド値を指定できます。
"weather = \"rain OR shine\"" この論理 OR は、引用符で囲まれた文字列の中に埋め込まれているため、関係演算子として処理されません。このクエリ文字列では、weather フィールドに「rain or shine」という文字列を含むドキュメントが取得されます。

数値フィールドのクエリ

数値フィールドの値は、整数、小数、指数として記述できます。 数値フィールでは、等価演算子に加え、各種の関係演算子(<<=>>=)を使用できます。不等価(!=)演算子は使用できません。数値フィールドのクエリ文字列の例を次に示します。

"quantity = 10000"
"size: 4"
"price < 9.99"
"theta > 1.5E-2"

日付フィールドのクエリ

日付フィールドの値は、yyyy-mm-dd form の形式で記述する必要があります。月と日にちが 1 桁の場合、先頭のゼロは省略可能です。日付フィールドでは、等価演算子に加え、各種の関係演算子(<<=>>=)を使用できます。不等価演算子は使用できません。式の前に NOT 演算子を付けて否定を表現することもできます。日付フィールドのクエリ文字列の例を次に示します。

"start_date: 2012-05-20"
"end_date: 2013-5-1"
"birthday >= 2000-12-31"
"NOT birthday = 2000-12-25"

地理的位置フィールドのクエリ

地理的位置フィールドでは関係演算子は使用できません。そのため、地理的位置フィールドをクエリ文字列で直接指定することはできません。Search API には、地理的位置フィールドのクエリに使用できる特殊な関数が 2 つ用意されています。

geopoint(lat,long)
緯度と経度を指定して地理的位置を定義します。
distance(point1, point2)
2 つの地理的位置の距離をメートル単位で計算します。それぞれの位置は、地理的位置フィールドの名前を使用するか geopoint 関数の呼び出しで指定できます。この関数の両方の引数にフィールド名を指定することはできない点に注意してください。少なくとも一方の引数は定数でなければなりません。

これらの関数を使用すると、ある場所を起点とした相対的な位置を取得するクエリを作成できます。次の例では、「survey_marker」と「home」という名前の地理的位置フィールドを含むドキュメントがインデックスに登録されていることを前提としています。

クエリ文字列 コメント
"distance(survey_marker, geopoint(35.2, 40.5)) < 100" 指定した地理的位置からの距離が 100 メートル未満のマーカーを探します。
"distance(home, geopoint(35.2, 40.5)) > 100" 指定した地理的位置からの距離が 100 メートルを超える建物を探します。

位置情報を使用するアプリケーションでは、ブラウザから情報を受け取るのが一般的です。位置情報はユーザーが許可していれば IP アドレスから推定できるほか、ユーザーに郵便番号を入力してもらうこともできます。また、Google Maps Geolocation API など、他の API から取得することもできます。

複数のフィールドのクエリ

複数のフィールドのクエリ式を空白文字で区切って続けて記述することで、1 つのクエリに結合できます。それぞれの式の間に暗黙的に AND があるものとして処理されるため、すべての式に一致するドキュメントだけが取得されます。式の間に AND 演算子や OR 演算子を明示的に追加したり、ロジックを明確にするために括弧を使用したりすることもできます。

クエリ文字列 コメント
"product=piano manufacturer=steinway"
"product=piano AND manufacturer=steinway"
Steinway のすべてのピアノを取得します。条件を区切るスペースは暗黙的に論理 AND であるとみなされます。2 つ目の形式は、これを明示的に指定したものです。
"product=piano AND NOT manufacturer=steinway" Steinway 以外のすべてのピアノを取得します。
"product=piano AND price<2000" 低価格のピアノを取得します。

グローバル検索とフィールド検索の組み合わせ

クエリ文字列には、グローバル検索の式とフィールド検索の式をいくつでも含めることができます。式を区切るスペースは AND として扱われます。ORAND を括弧と組み合わせて明示的に使用することもできます。それぞれの式がその種類の条件に該当するルールに従って処理されます。

クエリ文字列コメント
"keyboard great price<5000"
"keyboard AND great AND price<5000"
いずれかのテキスト フィールド、HTML フィールド、Atom フィールドに「great」と「keyboard」という単語を含み、かつ値が 5,000 未満の price フィールドがあるドキュメントが取得されます。暗黙的に AND があるものとして、2 つ目の形式と同じように処理されます。
"keyboard OR product=piano" product フィールドに piano を含むドキュメント、またはテキスト フィールド、HTML フィールド、Atom フィールドのいずれかに keyboard を含むドキュメントが取得されます。