Google App Engine:Gql LIKEクエリを実行することは可能ですか?


123

本当にシンプルなもの。SQLでは、テキストフィールドでいくつかの文字を検索する場合は、次のようにします。

SELECT blah FROM blah WHERE blah LIKE '%text%'

App Engineのドキュメントには、これを達成する方法についての言及はありませんが、確かにそれは一般的な十分な問題ですか?


3
継続する問題は、GAEデータストアをRelational /〜SQLデータベースであるかのように使用しようとする人々を中心に展開します。GoogleがGQLを導入することで、人々はSQLシステムの観点からさらに考えるようになります。しかし、これが正しいアプローチであるかどうかはわかりませんが、Googleが誰にとっても移行をより簡単にしようとしていることを理解しています。
fuentesjr 2009年

回答:


81

App EngineのデータベースバックエンドであるBigTableは、数百万のレコードに拡張されます。このため、十分にデータが設定されたテーブルではパフォーマンスが非常に悪くなるため、App Engineではテーブルスキャンを実行するクエリを実行できません。

つまり、すべてのクエリでインデックスを使用する必要があります。これは、あなただけ行うことができる理由です=>そして<クエリ。(実際に実行することもできます!=が、APIは>and <クエリの組み合わせを使用してこれを実行します。)これは、開発環境が実行するすべてのクエリを監視し、不足しているインデックスを自動的に追加する理由でもあります。index.yamlファイルにます。

LIKEクエリのインデックスを作成する方法がないため、クエリを使用できません。

この詳細については、このGoogle IOセッションをご覧ください。


77

私は同じ問題に直面していますが、Google App Engineページで何かを見つけました:

ヒント:クエリフィルターには、文字列値の一部のみを一致させる明示的な方法はありませんが、不等式フィルターを使用してプレフィックスの一致を偽造できます。

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
            "abc",
            u"abc" + u"\ufffd")

これは、すべてのMyModelエンティティを、文字abcで始まる文字列プロパティpropと一致させます。Unicode文字列u "\ ufffd"は、可能な最大のUnicode文字を表します。プロパティ値がインデックスで並べ替えられている場合、この範囲内の値は、指定されたプレフィックスで始まるすべての値です。

http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html

多分これはトリックを行うことができます;)


6
+1これは、大文字と小文字が区別されることを指摘する価値があります。幸い、クエリを実行しているフィールドのデータは、格納する前に小文字に変換されます。
Cuga

12

App EngineはLIKEクエリをサポートしていませんAltough、プロパティを見ていListPropertyStringListPropertyを。これらのプロパティで同等性テストが行​​われると、テストは実際にはすべてのリストメンバーに適用されます。たとえば、list_property = value値がリストのどこかにあるかどうかのテストです。

この機能は、LIKEクエリがない場合の回避策として使用される場合があります。たとえば、この投稿で説明されているように、単純なテキスト検索を実行できます


3
投稿はもう存在しません
mwm

9

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)います。



3

Objectifyをご覧ください。これは、データストアアクセスAPIのようなものです。具体的にはこの質問に関するFAQがあります。ここに答えがあります

likeクエリを実行する方法(LIKE "foo%")
格納および検索時に順序を逆にすると、startWithまたはendWithのようなことができます。希望する開始値と希望する値のすぐ上の値で範囲クエリを実行します。

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");

1
「次を含む」ではなく「次で始まる」を検索します。
Hardik Patel 2017

1

ここをフォローするだけです: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(...)

1

これをGAE Datastore低レベルJava APIでテストしました。私と完璧に動作します

    Query q = new Query(Directorio.class.getSimpleName());

    Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
    Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
    Filter filterNombre =  CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);

    q.setFilter(filter);

1
これは接頭辞で機能しますが、文字列の末尾から一致させたい場合はどうなりますか?たとえば-sdfdsabcでabcを検索したい場合、sdfdsabcを返す必要があります
user1930106

1

一般的に、これは古い投稿ですが、「LIKE」または「ILIKE」を生成する方法は、「> =」クエリからすべての結果を収集し、次に、Pythonで結果をループすることです。探しています。

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検索を実行することはできませんが、文字列内の単語を検索する必要がある場合は、Arraylistを作成するとうまくいきます。

@Index
    public ArrayList<String> searchName;

次に、objectifyを使用してインデックスを検索します。

List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();

これにより、検索で行った世界を含むすべてのアイテムのリストが表示されます


0

もし LIKE '%text%'常に1つまたはいくつかの単語(置換を考える)と比較し、データの変化が遅い場合(ゆっくりとは、インデックスを作成および更新するために、価格とパフォーマンスの両方で法外に高価ではないことを意味します)、Relation Index Entity(RIE)答えかもしれません。

はい、追加のデータストアエンティティを作成し、適切に入力する必要があります。はい、試してみる必要があるいくつかの制約があります(GAEデータストアのリストプロパティの長さの上限は5000です)。しかし、結果の検索は非常に高速です。

詳細については、JavaとOjbectifyを使用したRIEとPython使用したRIEの投稿を参照してください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.