谷歌应用引擎:是否可以进行 Gql LIKE 查询?
-
09-06-2019 - |
题
真的很简单。在 SQL 中,如果我想在文本字段中搜索几个字符,我可以这样做:
SELECT blah FROM blah WHERE blah LIKE '%text%'
App Engine 的文档没有提及如何实现这一点,但这肯定是一个足够常见的问题吗?
解决方案
BigTable 是 App Engine 的数据库后端,将扩展到数百万条记录。因此,App Engine 不允许您执行任何会导致表扫描的查询,因为对于填充良好的表来说,性能将非常糟糕。
换句话说,每个查询都必须使用索引。这就是为什么你只能做 =
, >
和 <
查询。(事实上你也可以这样做 !=
但 API 使用以下组合来完成此操作 >
和 <
查询。)这也是开发环境监视您执行的所有查询并自动将任何缺失的索引添加到您的查询中的原因。 index.yaml
文件。
没有办法为a建立索引 LIKE
查询,因此它根本不可用。
观看 这次 Google IO 会议 对此有更好、更详细的解释。
其他提示
我面临同样的问题,但我在谷歌应用程序引擎页面上发现了一些东西:
提示:查询过滤器没有明确的方法来仅匹配字符串值的一部分,但您可以使用不等式过滤器来伪造前缀匹配:
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
也许这可以解决问题;)
虽然 App Engine 不支持 LIKE 查询,但请查看属性 列表属性 和 字符串列表属性. 。当对这些属性进行相等测试时,该测试实际上将应用于所有列表成员,例如, list_property = value
测试该值是否出现在列表中的任何位置。
有时,此功能可以用作缺少 LIKE 查询的解决方法。例如,它可以做到 简单的文本搜索,如本文所述.
你需要使用 搜索服务 执行类似于 SQL 的全文搜索查询 LIKE
.
盖利克 提供领域特定语言来执行更多操作 用户友好的搜索查询. 。例如,以下代码片段将找到从最新书排序的前十本书,标题包含 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 的匹配运算符 =~
。它支持以下功能 distance(geopoint(lat, lon), location)
以及。
App Engine推出通用型 全文检索服务 在支持数据存储的版本 1.7.0 中。
详细信息在 公告.
有关如何使用此功能的更多信息: https://cloud.google.com/appengine/training/fts_intro/lesson2
看看对象化 这里 ,它就像一个数据存储访问 API。这个问题有专门的FAQ,这里是答案
如何进行类似查询(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/在里面.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(...)
我使用 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);
一般来说,即使这是一篇旧文章,生成“LIKE”或“ILIKE”的一种方法是收集“>=”查询的所有结果,然后在 python(或 Java)中循环结果以获取包含您想要的内容的元素。正在寻找。
假设您想过滤给定 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)
不可能在数据存储应用程序引擎上进行 LIKE 搜索,但是如果您需要搜索字符串中的单词,创建 Arraylist 就可以解决问题。
@Index
public ArrayList<String> searchName;
然后使用 objectify 在索引中进行搜索。
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
这将为您提供一个列表,其中包含包含您在搜索中所做的世界的所有项目
如果 LIKE '%text%'
总是与一个或几个单词(考虑排列)进行比较,并且您的数据变化缓慢(缓慢意味着创建和更新索引的价格和性能都不是太昂贵),那么关系索引实体(RIE)可能是答案。
是的,您将必须构建额外的数据存储实体并适当地填充它。是的,您必须解决一些限制(其中之一是 GAE 数据存储中列表属性的长度限制为 5000)。但搜索结果却快如闪电。
详情请看我的 使用 Java 和 Ojbectify 的 RIE 和 使用 Python 进行 RIE 帖子。
“喜欢”经常被用作文本搜索的穷人替代品。对于文本搜索,可以使用 嗖嗖-AppEngine.