gae/pythonでの全文検索の現状のbest practice

323 views
Skip to first unread message

Yosuke Suzuki

unread,
Mar 7, 2011, 7:14:22 PM3/7/11
to google-app-...@googlegroups.com
鈴木と申します。

GAE/Pythonで開発しておりますが、全文検索の実装について
お知恵を拝借できればと思います。

現状、以下のように全文検索を実装しています。

Yahoo形態素解析で検索対象の文章を分かち書き

StringListPropertyにわかち書きした単語を保存

StringListPropertyにfilterをかけて検索

1キーワードの際にはこれで特に不便はないのですが、
やはり複数ワードでの検索も実装したいと思います。

2キーワードまでであれば、同じStringListPropertyに対してfilterを2度がけ
するということで実装できていますが、
3度、4度がけするとindexのbulidでエラーになってしまいます。

また、ユーザーが入力した検索ワードを分かち書きすることもできていないので、
そこも問題です。

searchableモデルを使う方法、イアンさんのmisopotateなどの実装も
ネットでみかけました。

できればpure python(GAEで完結する形)での実装をしたいのですが、
現状のベストプラクティスだと思われるパターンがあれば、
ご教授いただけないでしょうか?

--
--------------------------
Yosuke Suzuki

Takashi Matsuo

unread,
Mar 7, 2011, 9:17:04 PM3/7/11
to google-app-...@googlegroups.com, Yosuke Suzuki
鈴木さん

いくつかオプションがあります。

1. 全文検索のリリースを待つ
ただし、いつ出るかは言えません。

2. Google Custom Search を使用
パブリックなページでしか使えません。

3. Task Queue + Channel API を使って検索を実現
(TaskQueue 内で複数の Query を投げ、インメモリで複数の結果に対してさらに処理を行い、結果を Channel API にて通知)
自分で試したわけではないですが、理論的には実現できそうです。

4. 3を動かすために Servers API を使用するのも良いアイデアかもしれません。
下記にあるように現在 Trusted Tester を募集しています。
http://groups.google.com/group/google-appengine/browse_thread/thread/1ae930fe73874fdd/351f71f0f016ef40

他の方もアイデアがあればぜひお知らせください。

-- matsuo

> --
> このメールは Google グループのグループ「Google-App-Engine-Japan」の登録者に送られています。
> このグループに投稿するには、google-app-...@googlegroups.com にメールを送信してください。
> このグループから退会するには、google-app-engine...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/google-app-engine-japan?hl=ja からこのグループにアクセスしてください。
>
>

--
Takashi Matsuo
Developer Relations
Developer Advocate for Google App Engine/iGoogle
Google Japan, Inc.

松本 勇気

unread,
Mar 8, 2011, 10:39:51 AM3/8/11
to Google-App-Engine-Japan
初めまして、松本と申します。
gae/pythonでいくつかWebアプリを作ってます。

自分は全文検索を自作しました。
形態素解析機に関しては、以下のigo-pythonを使うか、n-gramで分かち書きする場合は簡単ですので自作です。
http://pypi.python.org/pypi/igo-python/

簡単に説明します。
転置インデックス用のモデルを用意して検索を実現しています。
key_nameに単語、ListPropertyに、その単語を含む対象文書のKeyを保存。
検索時は、検索ワードを分かち書きして、各単語で転置インデックスを取得。
複数ワードの時は、必要に応じてKeyのListをAnd処理なりOr処理なりして、必要な結果のみ引っ張ってこれます。

今のところ単純な検索しか実現しておらず、検索スコアを算出できておりませんがこんな感じです。
検索スコアの算出も実装する予定です。

転置インデックスの作成はtaskQueueにでも投げておけば、長い文書でも問題ないかと思います。

当方、プログラミング歴数ヶ月なので、穴はあるかと思いますが、このような形で実装しています。
そのうち、ブログの方にまとめておきますので、参考になれば幸いです。

もっと良いアイディアがないか模索中です。
Yuki Matsumoto
Innovation Hacks http://ut-innovation-hack.blogspot.com/

Yosuke Suzuki

unread,
Mar 8, 2011, 9:19:38 PM3/8/11
to google-app-...@googlegroups.com
松本さん

どうも、情報ありがとうございます。
非常に参考になりました。

> 自分は全文検索を自作しました。
> 形態素解析機に関しては、以下のigo-pythonを使うか、n-gramで分かち書きする場合は簡単ですので自作です。
> http://pypi.python.org/pypi/igo-python/

これは使ってみようと思います。

> 簡単に説明します。
> 転置インデックス用のモデルを用意して検索を実現しています。
> key_nameに単語、ListPropertyに、その単語を含む対象文書のKeyを保存。
> 検索時は、検索ワードを分かち書きして、各単語で転置インデックスを取得。
> 複数ワードの時は、必要に応じてKeyのListをAnd処理なりOr処理なりして、必要な結果のみ引っ張ってこれます。
>
> 今のところ単純な検索しか実現しておらず、検索スコアを算出できておりませんがこんな感じです。
> 検索スコアの算出も実装する予定です。
>
> 転置インデックスの作成はtaskQueueにでも投げておけば、長い文書でも問題ないかと思います。

key_nameは日本語もOKなのですね。知りませんでした。
これも非常に参考になりました。
ありがとうございます。

ちなみに、文書の数が多いとListPropertyに登録できる制限にひかっかると
思うのですが、この点はなにか対処されていますでしょうか?

よろしくお願いします。

鈴木

> --
> このメールは Google グループのグループ「Google-App-Engine-Japan」の登録者に送られています。
> このグループに投稿するには、google-app-...@googlegroups.com にメールを送信してください。
> このグループから退会するには、google-app-engine...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/google-app-engine-japan?hl=ja からこのグループにアクセスしてください。
>
>

--
--------------------------
Yosuke Suzuki

松本 勇気

unread,
Mar 8, 2011, 9:43:46 PM3/8/11
to Google-App-Engine-Japan
鈴木さん

確かListPropertyは5000個以上の要素を持てなかったと思います。
この数を超えそうなシステムのときは、転置インデックスモデルに単語を保存するStringPropertyとナンバリングするための
IntegerProperty、Listがいっぱいであるということを示すBooleanPropertyを作って、リストがいっぱいになった時は、
同じワードをプロパティに持つ新しいインデックスを作成し、ナンバーをインクリメントしておいて、新しいインデックスに登録してゆくようにしていま
す。

ある単語のインデックスからキーを取り出したいときは、その単語で、単語プロパティをfilterして全件取得しListをマージしてます。

分かりにくいかもしれませんが、こんな感じです。
> > Innovation Hackshttp://ut-innovation-hack.blogspot.com/

tnkn

unread,
Mar 8, 2011, 10:41:51 PM3/8/11
to Google-App-Engine-Japan
初めまして鈴木さん。田中と申します。

当方はGAE/Javaで全文検索を実装しましたが、Datastoreの取り扱い方は基本的に
共通なので情報をシェアしたいと思います。

AND検索をする場合、リストプロパティ(以下LP)に対して一度のクエリで取得しようとすると、インデックス爆発の問題が発生します。そこで私は単語
の数だけクエリを分割して、得られた結果をプログラム上でマージしています。
「A B C」の検索であれば、LPに対してAで1回、Bで1回、Cで1回、合計3回+1回のクエリを発行します。
最後の1回はマージして得られたKeyのリストからエンティティの実体を取得する処理です。

こちらにtwitter風のサンプルを用意しましたので、いろいろ試してみてください。
なお、結果はすべて投稿日の降順でソートしてあります。
(全文検索サンプル)
http://tnkn1014.appspot.com/tweet/top

On 3月8日, 午前9:14, Yosuke Suzuki <yosuke.suz...@gmail.com> wrote:

Yosuke Suzuki

unread,
Mar 8, 2011, 11:15:58 PM3/8/11
to google-app-...@googlegroups.com
田中さん

ありがとうございます。

松本さんの情報でもありましたが、
単語にわけたうえで、複数回クエリを発行すればいいですね。

ちなみにこの場合、パフォーマンスが問題になりそうですが、
ボリュームが大きくなってもそれなりの時間で処理できそうでしょうか?

いただいたデモのページを試したところでは、数百ミリ秒で返ってきていますが、
2語、3語であれば問題にならないレベルでしょうか?

GAEは1リクエストを平均1秒以内で処理できないと、
スケールしないと聞いていますので、
それとの兼ね合いでどのぐらいまで複数ワードの検索に
対応するかを考えないといけいないのかと思っています。

よろしくお願いします。

鈴木

2011年3月9日12:41 tnkn <tnkn...@gmail.com>:

> --
> このメールは Google グループのグループ「Google-App-Engine-Japan」の登録者に送られています。
> このグループに投稿するには、google-app-...@googlegroups.com にメールを送信してください。
> このグループから退会するには、google-app-engine...@googlegroups.com にメールを送信してください。

Yosuke Suzuki

unread,
Mar 10, 2011, 10:29:37 PM3/10/11
to google-app-...@googlegroups.com
分かち書きの処理をigo-pythonに入れ替えて、
うまく動いてはいるのですが、
logを見ると下のようなメッセージが出るようになりました。

memory-leakがあるかもしれないということなのですが、
これは放っておくとやはりまずいのでしょうか?

同様の事象が出ている方などいらっしゃいましたら、
教えていただけないでしょうか?

pythonとkay-frameworkでアプリケーションを組んでいます。
分かち書きの処理をtask queで処理している部分で出ているメッセージです。

鈴木

200 533ms 14322cpu_ms 13603api_cpu_ms 0kb AppEngine-Google;
(+http://code.google.com/appengine)
0.1.0.2 - - [10/Mar/2011:19:14:19 -0800] "POST /_ah/queue/deferred
HTTP/1.1" 200 144 "http://hoge.appspot.com/hogehoge/"
"AppEngine-Google; (+http://code.google.com/appengine)"
"hoge.appspot.com" ms=533 cpu_ms=14322 api_cpu_ms=13603
cpm_usd=0.397961 queue_name=searchindex task_name=17679292436357128290
exit_code=101
I 2011-03-10 19:14:18.881
X-Appengine-Taskretrycount:0,
X-Appengine-Taskname:17679292436357128290,
X-Appengine-Queuename:searchindex, X-Appengine-Current-Namespace:
I 2011-03-10 19:14:19.352
Saved; key: __appstats__:058800, part: 90 bytes, full: 10660 bytes,
overhead: 0.001 + 0.009; link:
http://hoge.appspot.com/_ah/stats/details?time=1299813258881
C 2011-03-10 19:14:19.362
Exceeded soft process size limit with 183.34 MB after servicing 57
requests total
W 2011-03-10 19:14:19.362
After handling this request, the process that handled this request was
found to be using too much memory and was terminated. This is likely
to cause a new process to be used for the next request to your
application. If you see this message frequently, you may have a memory
leak in your application.

2011年3月9日0:39 松本 勇気 <kyud...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages