本当にシンプルなもの。SQL では、テキスト フィールドでいくつかの文字を検索したい場合、次のように実行できます。
SELECT blah FROM blah WHERE blah LIKE '%text%'
App Engine のドキュメントには、これを達成する方法については言及されていませんが、これは十分に一般的な問題なのでしょうか?
本当にシンプルなもの。SQL では、テキスト フィールドでいくつかの文字を検索したい場合、次のように実行できます。
SELECT blah FROM blah WHERE blah LIKE '%text%'
App Engine のドキュメントには、これを達成する方法については言及されていませんが、これは十分に一般的な問題なのでしょうか?
App Engine のデータベース バックエンドである BigTable は、数百万のレコードに拡張されます。このため、App Engine ではテーブル スキャンが発生するクエリを実行できません。データが十分に入力されたテーブルではパフォーマンスが大幅に低下するためです。
つまり、すべてのクエリでインデックスを使用する必要があります。=
これが、、>
および<
クエリしか実行できない理由です。(実際には実行することもできますが、API はとクエリ!=
の組み合わせを使用してこれを行います。)これが、開発環境が実行するすべてのクエリを監視し、不足しているインデックスをファイルに自動的に追加する理由でもあります。>
<
index.yaml
クエリのインデックスを作成する方法がないため、LIKE
単に利用できません。
この Google IO セッションを視聴して、これに関するより適切で詳細な説明を確認してください。
私は同じ問題に直面していますが、Google App Engine ページで何かを見つけました:
ヒント: クエリ フィルターには、文字列値の一部のみを照合する明示的な方法はありませんが、不等式フィルターを使用してプレフィックス マッチを偽装できます。
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
"abc",
u"abc" + u"\ufffd")
これは、文字 abc で始まる文字列プロパティ prop を持つすべての MyModel エンティティに一致します。Unicode 文字列 u"\ufffd" は、可能な最大の Unicode 文字を表します。プロパティ値がインデックスで並べ替えられている場合、この範囲に含まれる値は、指定されたプレフィックスで始まるすべての値です。
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
多分これはトリックを行うことができます;)
App Engine は LIKE クエリをサポートしていませんが、プロパティListPropertyとStringListPropertyを見てください。これらのプロパティに対して等価性テストが実行されると、テストは実際にはすべてのリスト メンバーに適用されます。たとえば、list_property = value
値がリストのどこかに表示されるかどうかをテストします。
この機能は、LIKE クエリがない場合の回避策として使用されることがあります。たとえば、この投稿で説明されているように、単純なテキスト検索を実行できます。
SQL と同様の全文検索クエリを実行するには、検索サービスを使用する必要がありますLIKE
。
Gaelykは、よりユーザーフレンドリーな検索クエリを実行するためのドメイン固有言語を提供します。たとえば、次のスニペットは、タイトルが を含みfern
、ジャンルが完全に一致する最新のものからソートされた最初の 10 冊の本を検索しthriller
ます。
def documents = search.search {
select all from books
sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
where title =~ 'fern'
and genre = 'thriller'
limit 10
}
Like は Groovy の一致演算子として記述され=~
ます。などの機能にも対応しdistance(geopoint(lat, lon), location)
ています。
App Engineは、データストアをサポートするバージョン 1.7.0 で汎用の全文検索サービスを開始しました。
詳細はお知らせにて。
これを使用する方法の詳細: https://cloud.google.com/appengine/training/fts_intro/lesson2
こちらの Objectify をご覧ください。これはデータストア アクセス API のようなものです。具体的には、この質問に関する FAQ があります。ここに回答があります
like クエリ (LIKE "foo%") を実行するに
はどうすればよいですか? 保存と検索の順序を逆にすると、startWith や endWith のようなことができます。必要な開始値と、必要な値のすぐ上の値を使用して範囲クエリを実行します。
String start = "foo";
... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
こちらに従ってください:init.py#354 "> http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/ init .py#354
できます!
class Article(search.SearchableModel):
text = db.TextProperty()
...
article = Article(text=...)
article.save()
To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:
query = article.all().search('a search query').filter(...).order(...)
データストア アプリ エンジンで LIKE 検索を実行することはできませんが、文字列内の単語を検索する必要がある場合に Arraylist を作成するとうまくいきます。
@Index
public ArrayList<String> searchName;
次に、objectify を使用してインデックスを検索します。
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
これにより、検索で行った世界を含むすべてのアイテムのリストが表示されます
一般に、これは古い投稿ですが、「LIKE」または「ILIKE」を生成する方法は、「>=」クエリからすべての結果を収集し、Python (または Java) で結果をループして、を探しています。
aq='luigi' を指定してユーザーをフィルタリングしたいとしましょう
users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))
for _qry in qry:
if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
users.append(_qry)
常に1つまたはいくつかの単語と比較しLIKE '%text%'
(順列を考えてください)、データの変化が遅い場合(ゆっくりとは、インデックスの作成と更新に、価格とパフォーマンスの両方で法外な費用がかからないことを意味します)、Relation Index Entity(RIE)答えかもしれません。
はい、追加のデータストアエンティティを構築し、適切に入力する必要があります。はい、いくつかの制約があります(1つはGAEデータストアのリストプロパティの長さの5000の制限です)。しかし、結果の検索は非常に高速です。
詳細については、JavaとOjbectifyを使用したRIEおよびPythonを使用したRIEの投稿を参照してください。
「いいね」は貧乏人のテキスト検索の代用としてよく使われます。テキスト検索には、Whoosh-AppEngineを使用できます。