検索のベスト プラクティス

このドキュメントでは、Search API を使用する際のおすすめの方法を紹介します。ここでは、クエリ文字列を単一引用符(‘’)で囲んで示しています。‘field:"some text" some-value’ のように、二重引用符で囲まれた複数語のフレーズを含むクエリを見分けやすくするためです。

Index.put() と Index.delete() を一括で呼び出す

ドキュメントのインデックスを追加または削除するときは、ドキュメントを一度に 200 個まで渡すことができます。この方法を使用すれば、一度に 1 つずつ処理するよりもはるかに効率的です。

ドキュメントをランクに基づいて事前に並べ替える

デフォルトでは、検索結果はランクの降順に並べ替えられます。各ドキュメントのランクは、Search API のデフォルトの設定では 2011 年 1 月 1 日からの秒数に設定されます。これにより、新しいドキュメントから先に返されるようになっています。ただし、ドキュメントを追加された順に並べ替える必要がなければ、ランクを別の目的に使用することもできます。たとえば不動産のアプリケーションであれば、顧客が最も知りたい情報は価格であるため、ランクを住宅価格に設定してデフォルトで並べ替えると効率的です。

価格が安い順と高い順のように、並べ替え順序を複数使用する場合は、それぞれの順序に対するインデックスを個別に作成できます。たとえば、一方のインデックスを rank = price、もう一方を rank = MAXINT-price(ランクは正の値でなければならないため)のように設定します。

ランクを並べ替えキーとして使用すると検索のパフォーマンスが向上します。他の並べ替えキーを使用する場合は、並べ替えオプションを使用して、検索結果に含まれるドキュメントの数を 10,000 個までに制限する必要があります。この場合、並べ替えの対象となるドキュメントは、ランクに基づく並べ替え順序で決まります。詳しくは、並べ替えオプションの説明をご覧ください。

ブール値のデータには 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_rangeprice_0_10price_11_20price_21_30price_31_40 のような価格帯のカテゴリを格納する price_41_lots というフィールドを作成します。このようにすると、並べ替えをまったく行わずに、費用が $21~$40 のすべてのレストランを ‘price_range:price_21_30 OR price_range:price_31_40’ というクエリで検索できます。多くの場合、適切なカテゴリは不明確ですが、この手法を使用すれば、‘... AND price>25 AND price<35’ のような高コストのクエリで検索結果を選別しなくても、多数のドキュメントを除外できます。

一致のスコア付けは必要がない限り行わない

スコア付けはドキュメントがクエリにどの程度一致するかを示すのに使用されます。ただし、スコアで並べ替える予定がなければ、検索が遅くなるだけなのでスコア付けはリクエストしないでください。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Python 2 の App Engine スタンダード環境