【发布时间】:2010-12-02 12:48:45
【问题描述】:
我将 Google App Engine (Java) 与 JDO 结合使用。我怎样才能做 JDO 等效的
select * from table where field like '%foo%'
到目前为止,我看到的唯一建议是使用 Lucene。开箱即用的 GAE 无法实现这种基本功能,这让我感到有点惊讶。
【问题讨论】:
标签: google-app-engine full-text-search jdo
我将 Google App Engine (Java) 与 JDO 结合使用。我怎样才能做 JDO 等效的
select * from table where field like '%foo%'
到目前为止,我看到的唯一建议是使用 Lucene。开箱即用的 GAE 无法实现这种基本功能,这让我感到有点惊讶。
【问题讨论】:
标签: google-app-engine full-text-search jdo
您不能在 App Engine 上进行这种类型的子字符串搜索。这样做的原因是 App Engine 数据存储区被构建为可扩展的,并且拒绝执行它不能满足索引的任何查询。像这样索引查询几乎是不可能的,因为它需要搜索每条记录的全部“字段”属性以查找匹配项。您在其上运行此查询的任何关系数据库都将通过执行全表扫描并单独检查每条记录来执行它 - 至少可以说是不可扩展的。
正如您已经发现的那样,解决方案是使用全文索引,例如 Lucene。有一些库可以在 App Engine 上运行 Lucene,例如 GAELucene。这也为您提供了正确的全文搜索的能力,而不是简单的子字符串匹配。
【讨论】:
tl;dr:管理您自己的多值搜索属性并对其执行等于查询。
详情: 对于那些寻找简单和 DIY 的人,您可以执行以下操作:
在您的实体上,创建一个多值 searchTerms 属性。这将包含实体的可搜索项。
将实体的可搜索文本拆分为单词。这些词将是实体唯一可搜索的部分。你可以从分割空格开始,或者你可以添加一些基本的词干。例如。在处理电子邮件地址时,您可能希望将用户和域部分分开放置,以便可以搜索两者。如果您的实体已更新,您将需要重建此属性。
要执行搜索,请将搜索输入拆分为单词(如果需要,执行基本词干提取),然后使用等于运算符将每个单词作为过滤器添加到 searchTerms 属性。
(多值属性上的 = 运算符询问 any 值是否等于过滤器。)
例如(使用Objectify):
Query query = dao.ofy().query(Recipe.class);
for (String term : search.toLowerCase().split(" ")) {
query = query.filter("searchTerms =", term);
}
【讨论】: