水曜日, 9月 30, 2009

【Google App Engine】 Low level APIで前方一致検索およびPagingについて このエントリーを含むはてなブックマーク


 JDOが全然使えないことが明らかになるにつれ、最近ではLow level APIを使う方も多くなってきた。Low level APIは、シンプルで扱いやすく、パフォーマンスにも問題ないことがうけて支持されているのだろう。しかし、機能的には全然足りないので、自分たちで何とか解決しなければならない課題も多い。前方一致検索もその一つである。

Low level APIで前方一致かつPagingが難しい件

 前方一致検索は、JDOではcontent.startsWithを使えばできるようであるが、Low level APIでも、検索項目をソートすることで一応できることはできる。しかしPagingについては、2Page目以降を特定する方法が必要ななため、できないと思っていた。
 例えば、下図のように、”コーヒー”で前方一致検索した場合に、同じ商品名の”コーヒー010”が複数存在する可能性があるため、次ページにおいて、どのレコードから表示すればよいかわからない。この問題は、Low level APIでは、GREATER_THAN_OR_EQUALなどのInequality filterが、1つしか使えないという制約に起因するものである。(追記10/29:LESS_THANも使えることがわかっている。参照=>Keyとカウンタは別々に考えるといいかも
)そこで、「複雑なクエリのためのプロパティを仕込んでおく方法」を参考に、前方一致検索でかつPagingする方法を考えてみた。ただ、さらに安い順でソートしたり、全文検索などはできない。これらについては、TaskQueueを使って対応するしかないと考えている。
 また、ここでは、商品のデータ件数は無限にあるという前提で考えている。小規模なものであれば考える必要はないのかもしれないが、これまで繰り返し述べているように、クラウドの最大のメリットはスケーラビリティだと思っているので、それを阻害するような制約は排除すべきであると思う。



実装方法およびサンプル

具体的には以下のようにする。

1Page目:

キーワード(word=”コーヒー”)で検索する。Low-level Datastore APIのQueryで、商品名プロパティに対して条件をGREATER_THAN_OR_EQUAL指定。Reflex GAEのEntityConverter#convertでCondition指定をし、対象項目が指定されたwordで始まっていなければ結果に含めないようにする。(この処理はIn Memory)

2Page目以降:

キーワード(word=”コーヒー” )、最後の商品名(nextword=“コーヒー010”)、および、最後の連番(number=009)を指定する。
Low-level Datastore APIのQueryで、商品名+連番プロパティに対してnextword + number条件をGREATER_THANで指定。 EntityConverter#convertでCondition指定をし、対象項目が指定されたwordで始まっていなければ結果に含まないようにする。 (この処理はIn Memory)



前方一致でかつPagingを行うサンプル

1ページ目
2ページ目

0 件のコメント:

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。