Google App Engine:是否可以进行 Gql LIKE 查询?

发布于 2024-08-19 15:18:57 字数 169 浏览 5 评论 0原文

真的很简单。在 SQL 中,如果我想在文本字段中搜索几个字符,我可以这样做:

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

App Engine 的文档没有提及如何实现这一点,但这肯定是一个足够常见的问题?

Simple one really. In SQL, if I want to search a text field for a couple of characters, I can do:

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

The documentation for App Engine makes no mention of how to achieve this, but surely it's a common enough problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

尬尬 2024-08-26 15:18:57

BigTable 是 App Engine 的数据库后端,将扩展到数百万条记录。因此,App Engine 不允许您执行任何会导致表扫描的查询,因为对于填充良好的表来说,性能将非常糟糕。

换句话说,每个查询都必须使用索引。这就是为什么您只能执行 =>< 查询。 (事实上​​,您也可以执行 !=,但 API 使用 >< 查询的组合来执行此操作。)这也是为什么开发环境会监视您执行的所有查询并自动将任何缺失的索引添加到您的 index.yaml 文件中。

无法为 LIKE 查询建立索引,因此它根本不可用。

观看此 Google IO会议对此有更好、更详细的解释。

BigTable, which is the database back end for App Engine, will scale to millions of records. Due to this, App Engine will not allow you to do any query that will result in a table scan, as performance would be dreadful for a well populated table.

In other words, every query must use an index. This is why you can only do =, > and < queries. (In fact you can also do != but the API does this using a a combination of > and < queries.) This is also why the development environment monitors all the queries you do and automatically adds any missing indexes to your index.yaml file.

There is no way to index for a LIKE query so it's simply not available.

Have a watch of this Google IO session for a much better and more detailed explanation of this.

美煞众生 2024-08-26 15:18:57

我面临同样的问题,但我在谷歌应用程序引擎页面上发现了一些东西:

提示:查询过滤器没有明确的方法来仅匹配字符串值的一部分,但您可以使用不等式过滤器伪造前缀匹配:

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

也许这可以解决问题;)

i'm facing the same problem, but i found something on google app engine pages:

Tip: Query filters do not have an explicit way to match just part of a string value, but you can fake a prefix match using inequality filters:

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

This matches every MyModel entity with a string property prop that begins with the characters abc. The unicode string u"\ufffd" represents the largest possible Unicode character. When the property values are sorted in an index, the values that fall in this range are all of the values that begin with the given prefix.

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

maybe this could do the trick ;)

书信已泛黄 2024-08-26 15:18:57

尽管 App Engine 不支持 LIKE 查询,但请查看属性 ListPropertyStringListProperty。当对这些属性进行相等性测试时,该测试实际上将应用于所有列表成员,例如,list_property = value 测试该值是否出现在列表中的任何位置。

有时,此功能可以用作缺少 LIKE 查询的解决方法。例如,它可以执行 简单文本搜索,如本文所述

Altough App Engine does not support LIKE queries, have a look at the properties ListProperty and StringListProperty. When an equality test is done on these properties, the test will actually be applied on all list members, e.g., list_property = value tests if the value appears anywhere in the list.

Sometimes this feature might be used as a workaround to the lack of LIKE queries. For instance, it makes it possible to do simple text search, as described on this post.

万劫不复 2024-08-26 15:18:57

您需要使用搜索服务来执行类似于 SQL LIKE.

Gaelyk 提供了特定于域的语言来执行更多操作用户友好的搜索查询。例如,以下代码片段将找到从最新书籍排序的前十本书,标题包含 fern
并且类型完全匹配 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 的匹配运算符 =~
它还支持诸如距离(地理点(纬度,经度),位置)等功能。

You need to use search service to perform full text search queries similar to SQL LIKE.

Gaelyk provides domain specific language to perform more user friendly search queries. For example following snippet will find first ten books sorted from the latest ones with title containing fern
and the genre exactly matching 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 is written as Groovy's match operator =~.
It supports functions such as distance(geopoint(lat, lon), location) as well.

§对你不离不弃 2024-08-26 15:18:57

App Engine 在 1.7 版中推出了通用全文搜索服务。 0 支持数据存储。

详情请参阅公告

有关如何使用此功能的更多信息:https://cloud.google.com/appengine/training /fts_intro/第2课

App engine launched a general-purpose full text search service in version 1.7.0 that supports the datastore.

Details in the announcement.

More information on how to use this: https://cloud.google.com/appengine/training/fts_intro/lesson2

楠木可依 2024-08-26 15:18:57

此处 ,它就像一个数据存储访问 API。这个问题有专门的FAQ,这里是答案

如何进行类似查询(LIKE“foo%”)
如果您在存储和搜索时颠倒顺序,则可以执行诸如 startWith 或 endWith 之类的操作。您可以使用所需的起始值和刚好高于所需值的值进行范围查询。

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

Have a look at Objectify here , it is like a Datastore access API. There is a FAQ with this question specifically, here is the answer

How do I do a like query (LIKE "foo%")
You can do something like a startWith, or endWith if you reverse the order when stored and searched. You do a range query with the starting value you want, and a value just above the one you want.

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
影子的影子 2024-08-26 15:18:57

只需按照这里:
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(...)

Just follow here:
init.py#354">http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/init.py#354

It works!

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(...)
南城追梦 2024-08-26 15:18:57

我使用 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);

I tested this with GAE Datastore low-level Java API. Me and works perfectly

    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);
缺⑴份安定 2024-08-26 15:18:57

一般来说,即使这是一篇旧文章,生成“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)

In general, even though this is an old post, a way to produce a 'LIKE' or 'ILIKE' is to gather all results from a '>=' query, then loop results in python (or Java) for elements containing what you're looking for.

Let's say you want to filter users given a q='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)
因为看清所以看轻 2024-08-26 15:18:57

不可能在数据存储应用程序引擎上进行 LIKE 搜索,但是如果您需要搜索字符串中的单词,创建 Arraylist 就可以解决问题。

@Index
    public ArrayList<String> searchName;

然后使用 objectify 在索引中进行搜索。

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

这将为您提供一个列表,其中包含包含您在搜索中所做的世界的所有项目

It is not possible to do a LIKE search on datastore app engine, how ever creating an Arraylist would do the trick if you need to search a word in a string.

@Index
    public ArrayList<String> searchName;

and then to search in the index using objectify.

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

and this will give you a list with all the items that contain the world you did on the search

寂寞陪衬 2024-08-26 15:18:57

如果 LIKE '%text%' 总是与一个或几个单词(考虑排列)进行比较,并且您的数据变化缓慢(缓慢意味着它的价格并不算昂贵 - 无论是价格方面还是性能方面 -创建和更新索引)那么关系索引实体(RIE)可能就是答案。

是的,您将必须构建额外的数据存储实体并适当地填充它。是的,您必须解决一些限制(其中之一是 GAE 数据存储中列表属性的长度限制为 5000)。但搜索结果却快如闪电。

有关详细信息,请参阅我的RIE with Java and OjbectifyRIE with Python 帖子。

If the LIKE '%text%' always compares to a word or a few (think permutations) and your data changes slowly (slowly means that it's not prohibitively expensive - both price-wise and performance-wise - to create and updates indexes) then Relation Index Entity (RIE) may be the answer.

Yes, you will have to build additional datastore entity and populate it appropriately. Yes, there are some constraints that you will have to play around (one is 5000 limit on the length of list property in GAE datastore). But the resulting searches are lightning fast.

For details see my RIE with Java and Ojbectify and RIE with Python posts.

贪了杯 2024-08-26 15:18:57

“喜欢”经常被用作文本搜索的穷人替代品。对于文本搜索,可以使用 Whoosh-AppEngine

"Like" is often uses as a poor-man's substitute for text search. For text search, it is possible to use Whoosh-AppEngine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文