使用Google App Engine和JDO进行全文搜索?

6
我正在使用Google App Engine(Java)和JDO。如何执行JDO等效的操作?
select * from table where field like '%foo%'

到目前为止,我看到的唯一建议是使用Lucene。我有点惊讶,这么基本的功能在GAE开箱即用的情况下却不可行。

2个回答

6
无法在App Engine上进行此类子字符串搜索。原因是App Engine数据存储被构建为可扩展的,并拒绝执行任何无法满足索引的查询。像这样的查询几乎不可能建立索引,因为它需要搜索每个记录的“field”属性的全部内容以进行匹配。在任何关系型数据库上运行此查询将通过执行完整的表扫描并逐个检查每条记录来执行它——至少可以说是不可扩展的。
正如你已经发现的那样,解决方案是使用全文索引,例如Lucene。有一些库可以在App Engine上运行Lucene,例如GAELucene。这还为您提供了适当的全文搜索功能,而不是简单的子字符串匹配。

Nick,感谢您的回复。数据存储是否可以创建一个基于单个单词而不是%foo%的索引?我的意思是,如果不是正则表达式式搜索,Google显然能够进行关键字搜索。我真正想要实现的是扫描一组食谱以查找关键字,因此也许我表达得不太清楚。谢谢。 - George Armhold
1
是的 - 你所指的是“倒排索引”,这是像Lucene这样的库使用的。对于Python,有SearchableModel实现了这种模式。如果你想的话,你也可以在Java中做同样的事情,但最好还是使用Lucene。 - Nick Johnson

1

简而言之: 管理自己的多值搜索属性并执行相等查询。

详情: 对于那些寻求简单和自助的人,您可以按照以下步骤操作:

  1. 在您的实体上创建一个多值属性 searchTerms。这将包含实体的可搜索项。

  2. 将实体的可搜索文本拆分成单词。这些单词将是实体唯一可搜索的部分。您可以从空格处开始拆分,或者您可以添加一些基本的词干处理。例如,在处理电子邮件地址时,您可能希望将用户和域部分分开,以便两者都可以进行搜索。如果更新了实体,则需要重新构建此属性。

  3. 要执行搜索,请将搜索输入拆分为单词(如有必要,执行基本的词干处理),并使用等于运算符将每个单词作为过滤器添加到 searchTerms 属性中。

    (多值属性上的 = 运算符询问是否有任何值等于过滤器。)

    例如(使用 Objectify):

    Query query = dao.ofy().query(Recipe.class);
    for (String term : search.toLowerCase().split(" ")) {
      query = query.filter("searchTerms =", term);
    }
    


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接