JDO で Google App Engine (Java) を使用しています。JDOに相当するものをどのように行うことができますか
select * from table where field like '%foo%'
これまでに見た唯一の推奨事項は、Lucene を使用することです。すぐに使える GAE では、この基本的なことができないことにちょっと驚いています。
JDO で Google App Engine (Java) を使用しています。JDOに相当するものをどのように行うことができますか
select * from table where field like '%foo%'
これまでに見た唯一の推奨事項は、Lucene を使用することです。すぐに使える GAE では、この基本的なことができないことにちょっと驚いています。
AppEngineでそのような部分文字列検索を実行することはできません。これは、App Engineデータストアがスケーラブルに構築されており、インデックスで満たすことができないクエリの実行を拒否するためです。このようなクエリのインデックス作成は、各レコードの「フィールド」プロパティ全体で一致するものを検索する必要があるため、ほぼ不可能です。このクエリを実行するリレーショナルデータベースは、全表スキャンを実行し、各レコードを個別にチェックすることで実行します。控えめに言っても、スケーラブルではありません。
すでにわかっているように、解決策は、Luceneなどのフルテキストインデックスを使用することです。GAELuceneなど、AppEngineでLuceneを実行するためのライブラリがあります。これにより、単純な部分文字列の照合ではなく、適切な全文検索の機能も提供されます。
tl;dr : 独自の多値検索プロパティを管理し、それに対して equals クエリを実行します。
詳細: シンプルで DIY なものを探している場合は、次のことができます。
エンティティで、複数値のsearchTerms
プロパティを作成します。これには、エンティティの検索可能なアイテムが含まれます。
エンティティの検索可能なテキストを単語に分割します。これらの単語は、エンティティの唯一の検索可能な部分になります。空白で分割することから始めることも、基本的なステミングを追加することもできます。たとえば、電子メール アドレスを扱う場合、ユーザー部分とドメイン部分を別々に配置して、両方を検索できるようにすることができます。エンティティが更新された場合は、このプロパティを再構築する必要があります。
検索を実行するには、検索入力を単語に分割し (必要に応じて基本的なステミングを実行します)、searchTerms
プロパティに対して equals 演算子を使用してそれぞれをフィルターとして追加します。
(=
多値プロパティの演算子は、フィルタと等しい値があるかどうかを尋ねます。)
例 ( Objectifyを使用):
Query query = dao.ofy().query(Recipe.class);
for (String term : search.toLowerCase().split(" ")) {
query = query.filter("searchTerms =", term);
}