真的很简单。在SQL中,如果我想在文本字段中搜索几个字符,我可以这样做:
SELECT blah FROM blah WHERE blah LIKE '%text%'
App Engine的文档没有提到如何实现这一点,但肯定这是一个常见的问题吗?
答案 0 :(得分:78)
BigTable是App Engine的数据库后端,它将扩展到数百万条记录。因此,App Engine将不允许您执行任何将导致表扫描的查询,因为对于填充良好的表,性能将是可怕的。
换句话说,每个查询都必须使用索引。这就是您只能进行=
,>
和<
查询的原因。 (事实上,您也可以执行!=
,但API使用>
和<
查询的组合来执行此操作。)这也是开发环境监视您执行的所有查询的原因将任何缺失的索引添加到index.yaml
文件中。
无法为LIKE
查询编制索引,因此它根本不可用。
请注意this Google IO session以获得更好更详细的解释。
答案 1 :(得分:75)
我面临同样的问题,但我在谷歌应用引擎页面上找到了一些东西:
提示:查询过滤器没有明确的方法来匹配字符串值的一部分,但您可以使用不等式过滤器伪造前缀匹配:
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
"abc",
u"abc" + u"\ufffd")
这将匹配每个MyModel实体,其字符串属性prop以字符abc开头。 unicode字符串u“\ ufffd”表示最大可能的Unicode字符。当属性值在索引中排序时,属于此范围的值是以给定前缀开头的所有值。
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
也许这可以解决问题;)
答案 2 :(得分:12)
Altough App Engine不支持LIKE查询,请查看属性ListProperty和StringListProperty。当对这些属性进行相等测试时,测试将实际应用于所有列表成员,例如,list_property = value
测试是否值出现在列表中的任何位置。
有时,此功能可能会用作缺少LIKE查询的解决方法。例如,它可以simple text search, as described on this post。
答案 3 :(得分:9)
您需要使用search service执行类似于SQL LIKE
的全文搜索查询。
Gaelyk提供了特定于域的语言来执行更多user friendly search queries。例如,以下代码段会找到前10本书,这些书从最新的书籍中排序,其中包含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
}
喜欢写为Groovy的匹配运算符=~
。
它还支持distance(geopoint(lat, lon), location)
等功能。
答案 4 :(得分:4)
App引擎在版本1.7.0中启动了支持数据存储的通用full text search service。
announcement中的详细信息。
有关如何使用此内容的更多信息:https://cloud.google.com/appengine/training/fts_intro/lesson2
答案 5 :(得分:3)
看看Objectify here,它就像一个数据存储区访问API。这个问题有一个常见问题解答,这里是答案
我如何进行类似查询(LIKE“foo%”)
如果在存储和搜索时颠倒顺序,则可以执行类似startWith或endWith的操作。您可以使用所需的起始值进行范围查询,并使用您想要的值。
String start = "foo";
... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
答案 6 :(得分:1)
请按照此处: init.py#354" &GT; 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(...)
答案 7 :(得分: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);
答案 8 :(得分:1)
一般来说,即使这是一个老帖子,也是一种产生“喜欢”的方式。或者&#39; ILIKE&#39;是收集来自&#39;&gt; =&#39;的所有结果。查询,然后循环导致python(或Java)包含您正在寻找的内容的元素。
我们假设你想过滤q =&#39; luigi&#39;
的用户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)
答案 9 :(得分:1)
无法在数据存储区应用引擎上进行LIKE搜索,如果需要搜索字符串中的单词,如何创建Arraylist就可以了。
@Index
public ArrayList<String> searchName;
然后使用objectify在索引中搜索。
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
这将为您提供一个列表,其中包含您在搜索中所做的世界的所有项目
答案 10 :(得分:0)
如果LIKE '%text%'
总是与一个或多个单词(认为排列)进行比较,并且您的数据变化缓慢(慢慢意味着创建和更新索引,价格和性能方面的成本并不高得太高)然后关系索引实体(RIE)可能是答案。
是的,您必须构建其他数据存储区实体并适当填充它。是的,您必须使用一些约束(GAE数据存储区中列表属性的长度限制为5000)。但由此产生的搜索速度很快。
有关详细信息,请参阅我的RIE with Java and Ojbectify和RIE with Python帖子。
答案 11 :(得分:0)
“喜欢”经常被用作穷人替代文本搜索。对于文本搜索,可以使用Whoosh-AppEngine。