このドキュメントでは、Search API を使用する際のおすすめの方法を紹介します。ここでは、クエリ文字列を単一引用符(‘’)で囲んで示しています。‘field:"some text" some-value’
のように、二重引用符で囲まれた複合語を含むクエリを見分けやすくするためです。
ブール値のデータには Atom フィールドを使用する
ブール値のデータは数値フィールドで並べ替えても効果的ではありません。代わりに Atom フィールドを使用し、定数(True/False、yes/no、0/1)を割り当てます。
否定よりも肯定を使用する
料理の種類が定義されていないレストランを識別する特別な語句を設定してあれば、‘NOT cuisine:undefined’
のようなクエリを使用してそれらのレストランを除外できます。ただし、このクエリの評価は、料理の種類がわかっているレストランを探す場合に比べて、課金対象のオペレーションという意味でも、実行時間という意味でもコスト高になります。このような場合は、料理の種類を示すフィールドを 1 つだけ使用する代わりに、cuisine
というフィールドと cuisine_known
という Atom フィールドの 2 つを使用します。料理の種類が定義されているレストランについては、最初のフィールドを実際の料理の種類に設定し、2 番目のフィールドを "yes"
に設定します。料理の種類がわからないレストランについては、料理の種類を ""
(空の文字列)に設定し、cuisine_known
を "no"
に設定します。このようにすれば、料理の種類がわかっているレストランを ‘cuisine_known:yes’
というクエリで探すことができ、否定を使用するよりもはるかに高速になります。
分離よりも結合を使用する
「OR」を使用した分離は、課金対象のオペレーションという意味でも、実行時間という意味でもコスト高になります。たとえば ‘cuisine:Japanese OR cuisine:Korean’
を検索する場合、より大きな料理のカテゴリを使用してドキュメントにインデックスを付けることもできます。この場合は、‘cuisine:Asian’
とするとクエリがシンプルになります。
クエリから同意反復を排除する
トロントにあるすべてのレストランを検索するとします。ドキュメントに「city」というフィールドが 1 つだけあるとすると、‘city:toronto AND NOT city:montreal’
というクエリの結果は ‘city:toronto’
の結果と同じになります。city が "toronto"
に設定されていれば、同時に "montreal"
に設定されることはないからです。この場合、検索する語句が 1 つだけであるため、2 番目のクエリの方がはるかに高速になります。最初のクエリでは、city が「toronto」に設定されたドキュメントのリストを取得してから、city が「montreal」でないすべての都市のリストを取得し、最後にそれらの 2 つのリストの共通部分を特定する必要があるため、3 段階の処理が必要になります。
範囲を絞り込んでから並べ替える
世界中のレストランの情報が格納されたアプリケーションで、現在のユーザーに対して近くのレストランを表示するとします。この方法の 1 つとして、ユーザーの所在地からの距離に基づいて該当するドキュメントを並べ替える方法が考えられます。しかし、レストランの情報が 1,000,000 件にも及ぶ場合、並べ替えの式を distance(geopoint(x, y), restaurant_loc) のように設定して ‘cuisine:japanese’
のようなクエリを実行しようとすると、実行にかなりの時間がかかります。このような場合は、クエリにフィルタを追加することで、該当するドキュメントを絞り込んでから並べ替えを行うと効果的です。1 つの解決策として、国、州、都市のような地理的なカテゴリを作成する方法があります。都市や州はユーザーの所在地から推測できます。このようにすると、クエリは ‘cuisine:japanese AND city:<user-city>’
のようになり、1,000,000 個のドキュメントを並べ替える必要はなくなるはずです。
並べ替えが最小限で済むように限定されたカテゴリを使用する
ランクを使用してレストランを価格帯で並べ替える場合、price_range
、price_0_10
、price_11_20
、price_21_30
、price_31_40
のような価格帯のカテゴリを格納する price_41_lots
というフィールドを作成します。このようにすると、並べ替えをまったく行わずに、費用が $21~$40 のすべてのレストランを ‘price_range:price_21_30 OR price_range:price_31_40’
というクエリで検索できます。適切なカテゴリがはっきりしないケースがほとんどですが、この方法であれば、‘... AND price>25 AND price<35’
のような高コストのクエリによる検索結果を精査する前に多数のドキュメントを除外できます。
一致のスコア付けは必要がない限り行わない
スコア付けはドキュメントがクエリにどの程度一致するかを示すのに使用されます。ただし、スコアで並べ替える予定がなければ、検索が遅くなるだけなのでスコア付けはリクエストしないでください。