GAE Hackathon Disc. 3 に参加してきました! 私とid:a2c (Twitter) がGoogle Appengineの日本語が対応する全文検索エンジンを作ってみました。
GAE では、データストアが Entity と言う概念で作られてるけど、Entityを検索する時に、データを完全一致しないと、データを取れないので、全文検索が難しくて、以下の状況になってる。
- 一応、SearchableModelというクラスを継承すれば、英文検索が出来るけど、日本語テキスト検索が全くできない。(英語でも結構ひどい)
- SearchModelで、英語検索しても、スペース文字で単語単位で切るので、単語を完全一致しないといけない。(つまり、informationがテキストに入ってるけど、infoで検索しても出てこない)
- SearchableModelでは、3文字以下の単語はインデクスしてくれないので、ほとんどの日本語はアウト
- 上の点の関係で、3文字以下の検索キーワードもアウト
- 検索キーワードが無視された場合、何でも、引っかかるので、検索結果が分かりにくい
a2cさんが以前に、いろいろ調べたり、試してみたりしてくれたので、いろいろ助かった。いい情報を取れたので、すごくいい話が当日にできました。
- GAEのAPI1.2で追加になったCronを使って転置インデックスの更新をしてみる
- GAE ハカソン事前MTG
- GoogleAppEngineのReq/Sec計って見た
- gae上でDataStore使わずにmemcacheで転置インデックス作ってみた。
- GoogleAppEngineのサーバサイドの処理時間をProfileで表示させる為にcProfile使う
- GAEのDatastoreが順調に肥大中
SearchableModelのAPIは基本的にいいと思ったので、SearchableModelと同じように、日本語対応できるSearchableModelを使いたいなと思いました。こう書けば、わりと簡単に検索できる。
from google.appengine.ext.search import SearchableModel | |
from google.appengine.ext.db import * | |
class Document(SearchableModel): | |
title = StringProperty(u"Title") | |
text = TextProperty(u"Body Text") |
... | |
Document.all().search(keyword) | |
... |
まず、SearchableModelがいろいろ、自分を参照したので、継承するのが難しかったから、別のモジュールにコピーして、forkすることにした。それで、この辺に単語の分け方を a2cが作ってくれた ngram実装に切り替えた。(ngramとは?) それで、SearchableModelのモジュールを変えるだけで、googleの実装と同じように使える。
検索キーワードをngramで分けて、インデクスを検索すると、ちゃんと部分的にデータが引っ張ってくる。 http://saichugen.appspot.com/ でテストアプリを見れる。コードはbitbucketで公開されてる。
これから、a2cさんともっと検索結果を取れるようにするのと、インデクスの容量をへらしたりするのと、分け方を自分で実装できるapiを導入したいと思うので、ぜひ期待してください