GAE Hackathon Disc. 3 に参加してきました! 私とid:a2c (Twitter) がGoogle Appengineの日本語が対応する全文検索エンジンを作ってみました。

GAE では、データストアが Entity と言う概念で作られてるけど、Entityを検索する時に、データを完全一致しないと、データを取れないので、全文検索が難しくて、以下の状況になってる。

  • 一応、SearchableModelというクラスを継承すれば、英文検索が出来るけど、日本語テキスト検索が全くできない。(英語でも結構ひどい)
  • SearchModelで、英語検索しても、スペース文字で単語単位で切るので、単語を完全一致しないといけない。(つまり、informationがテキストに入ってるけど、infoで検索しても出てこない)
  • SearchableModelでは、3文字以下の単語はインデクスしてくれないので、ほとんどの日本語はアウト
  • 上の点の関係で、3文字以下の検索キーワードもアウト
  • 検索キーワードが無視された場合、何でも、引っかかるので、検索結果が分かりにくい

a2cさんが以前に、いろいろ調べたり、試してみたりしてくれたので、いろいろ助かった。いい情報を取れたので、すごくいい話が当日にできました。

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を導入したいと思うので、ぜひ期待してください