GAE SearchAPI


Search API 調査

GAEの SearchAPIについて調査した内容を忘れないように残しておく。

Search API は、ドキュメント、インデックス、クエリ、結果という 4 つの主要な概念に基づいています。

ドキュメント

ドキュメント = Cloud Datastoreでいうエンティティ, データのこと。

インデックス内のドキュメントは一意のid(doc_id)を持っている。

ドキュメントに使用できるフィールド

  • テキスト - ワード単位で検索可能な文字列(全文検索用のフィールド)
  • Atom - 非表示の文字列(IDとか絞り込みで必要だが, 表示する必要のないフィールドかな)
  • 数値
  • 日付
  • 地理情報

ドキュメントの最大サイズは1MB。(1MB以上のドキュメントはなかなかないので問題なさそう)

インデックスに追加した後にドキュメントを変更することはできません。フィールドの追加や削除、フィールド値の変更もできません。ただし、ドキュメントを同じ doc_id を持つ新しいドキュメントに置き換えることはできます。

updateは出来ないので doc_id を指定し削除して再度作成する必要がある。

インデックス

インデックスからドキュメントを保存したり, ドキュメントを取得する。 RDBでいうTableのようなイメージ。

ドキュメントをグループごとに別のインデックスに入れてグループ単位で管理することも可能です。

EntityのKindごとにインデックスを分ける形で進めれば良さそう。

インデックスのデフォルトの最大サイズは10GBだが, リクエストをGCPに送れば200GBまで増やすことができる。
200GBまでスケールすれば普通の規模のアプリケーションなら問題なさそう。

クエリ

インデックスを検索するには, クエリ文字列といくつかの追加のオプションを使用してクエリを作成する。

ex: "name = takpy"

このように複数フィールドに対する条件を指定することもできる。
フィールドを指定しなかった場合は全てのフィールドを対象に検索が走る。

クエリオプション

  • 検索結果に返すドキュメントの数を制御する。
  • 検索結果に含めるドキュメント フィールドを指定する。
    • デフォルトでは、元のドキュメントのすべてのフィールドが検索結果に含められます。一部のフィールドのみを検索結果に含めるように指定できます(元のドキュメントへの影響はありません)。
  • 検索結果を並べ替える。
  • FieldExpressions を使用してドキュメントの「コンピューティングされたフィールド」を作成し、スニペットを使用して短縮されたテキスト フィールドを作成する。
  • (オフセットとカーソルを使用して)各クエリに一致したドキュメントの一部のみを返すことで、検索結果のページ分割をサポートする

Search APIをどう使っていくか

ドキュメント

doc_id

デフォルトだとSearch APIが勝手に生成してくれるが自分でdoc_idを指定することもできる。
Cloud Datastoreからデータが消えた時, 更新された時にどのドキュメントを削除するかの識別のために doc_id にEntityのIdを指定する。

doc_id を指定してドキュメントの取得はできるが, 他のフィールドと合わせての取得はできないのでもしクエリの条件に使いたい場合はフィールドに別途追加する必要がある。

ドキュメント 登録・削除

それぞれのアプリケーションでインデックスにドキュメントを登録・削除する必要がある。
ドキュメントを登録・削除を行わないとCloud Datastoreには存在するが検索で出てこない, 又は逆のようなことも起こってしまう。

index, err := search.Open("users")
if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
}
_, err = index.Put(ctx, user.Id, user)
if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
}

ドキュメントを検索・取得

こんな感じ。

index, err := search.Open("users")
index.Search(ctx, "Name = takpy", nil)