Answers:
BigTable是App Engine的数据库后端,它将扩展到数百万条记录。因此,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")
这会将每个MyModel实体与一个以字符abc开头的字符串属性prop匹配。unicode字符串u“ \ ufffd”表示最大的Unicode字符。在索引中对属性值进行排序时,属于此范围的值是所有以给定前缀开头的值。
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
也许这可以解决问题;)
尽管App Engine不支持LIKE查询,但请查看属性ListProperty和StringListProperty。当对这些属性进行相等性测试时,该测试实际上将应用于所有列表成员,例如,list_property = value
测试值是否出现在列表中的任何位置。
您需要使用搜索服务来执行类似于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的match运算符=~
。它还支持诸如此类的功能distance(geopoint(lat, lon), location)
。
在这里看看Objectify ,它就像一个数据存储访问API。具体有一个关于此问题的常见问题解答,这是答案
如何执行类似查询(如“ 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(...)
我使用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)中循环搜索包含您所需要内容的元素正在寻找。
假设您要过滤给定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)
无法在数据存储应用程序引擎上进行LIKE搜索,但是如果您需要搜索字符串中的单词,那么创建Arraylist可以解决问题。
@Index
public ArrayList<String> searchName;
然后使用objectify搜索索引。
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
这将为您提供一个列表,其中包含包含您在搜索中所做的世界的所有项目
如果LIKE '%text%'
始终将一个词或几个词进行比较(认为排列),并且您的数据变化缓慢(缓慢地表示创建和更新索引并不昂贵(从价格角度和性能角度而言),则不那么昂贵),然后使用关系索引实体(RIE)可能是答案。
是的,您将必须构建其他数据存储实体并适当地填充它。是的,您需要解决一些约束(GAE数据存储区中list属性的长度限制为5000个)。但是结果搜索很快。
有关详情请参阅我的Java和Ojbectify RIE和RIE使用Python的职位。
“喜欢”通常用作穷人的文本搜索替代品。对于文本搜索,可以使用Whoosh-AppEngine。