Google App Engineで全文検索 、階層カテゴリ検索(Googleさん、StorageのNumber of Indexesを増やしてくださいorz)

Google App Engine全文検索、階層カテゴリ検索のデモ作りました。


追記 appengine ja night #11の発表の録画をこちらで視聴できます。


http://kissrobber.appspot.com/gae_full_text_search/
とりあえず、データ件数は10000件ちょいのデモですが、速いです。
まだ試してないですが、もっとデータ増えてもイケるはずです。
もし要望があれば、実装の詳細は公開します。


GAE上での日本語対応の全文検索は、luceneを動かす試みや、compass?の様な実装等あったりしますが、
どれもデータ件数が多いと動かなかったり(数千件が上限でしょうか)、レスポンスが返ってこなかったりして、
実用レベルのものはまだ無いのではないかと思います。
既にある全文検索の仕組みをどうにかしてGAE上で動かすのではなくて、GAEスペシャルな全文検索を作りました。

仕組み概要

キーワード検索には形態素解析でバラしてから転置インデックスを作成しています。このデモには無いですがタグ検索やリストプロパティの検索等も同様の仕組で実現可能です。
送料無料、階層カテゴリ、価格帯等はコンポジットインデックスを利用したフィルタを使ってます。


他、色々あるんですが、とりあえず一番のポイントはコンポジットインデックスだと思います。
(サクサク返す為にはイン-メモリ-ソートを使わない事がポイント)


数千件程度ならインメモリソートでイケるかもしれませんが、数万件になってくるとキー以外のプロパティも取ってくる処理も含めてパフォーマンスが上がらないと思います。
composite-indexを使ってBigtableでソートしておけば、asKeyList()と転置インデックスで必要な件数分だけKeyを取得した時点でバッチgetしてレスポンスを返す事ができるので速いです。

注意

ここで、検索項目の組み合わせの数だけインデックス定義が必要になるという事に注意が必要です。
GAEの制約では、1エンティティあたりインデックス数が5000までという制限がありますが、
もう一つ重要な事でアプリ全体でインデックス定義が200までの制限があります(知らなかったorz)。


修正&追記[twitter:@najeira]さんに教えてもらってインデックス定義爆発(インデックス爆発じゃなくて)問題は解決しました。

つまり、
リストプロパティにワイルドカードを入れておく事によって、選択しないパターンを別定義する必要がなくなる。
階層カテゴリも複数持つようになるけど考え方は同じ。
なので1パターンで定義できる。
オーダーのパターン数だけ定義すればOKとなる。
という事です。ありがとうございます。



このインデックス定義の数ですが、検索に使用したい項目の数が増えると掛け算式に増えていきます
どういう事かと言うとこのデモの場合では、

  • 階層カテゴリ 5パターン
  • 価格帯 2パターン
  • コンビニ決済 2パターン
  • 送料無料 2パターン
  • 並び順 4パターン

通りの組み合わせのインデックスが必要で5×2×2×2×4=160個定義が必要になります。

ここで、

もう一つ条件を増やす、例えば"新着のみフラグ"を追加した場合はまた2パターン追加となって、
160×2=320になって200を越える為、Over Quotaとなりデプロイできません(開発環境では動いてしまうので気がつかない事無いように注意が必要)


これはデモなので検索項目数を調整してますが、
今お仕事で作ってるアプリでは、まさかこんなにインデックス定義(全組み合わせ数)が増えるとは思って無かった事と、200までの制限がある事を知らなかった事で、今納品できずに結構深刻な事態になってたりします。このままではGAE破産するかもorz...


とりあえず、Next Gen Queries早くリリースしてください。それまでの間インデックス定義の上限を大幅に増やしてくださいm(__)m

でも、

なんだかんだで、もうGAEとSlim3があれば何でも作れるような気がします。
俺はGoogle App Engineが好きです。