2009-09-30 71 views
4

我正在使用带有JDO的Google App Engine(Java)。我该如何做JDO等价物使用Google App Engine和JDO的全文搜索?

select * from table where field like '%foo%' 

我目前看到的唯一建议是使用Lucene。我有点惊讶,这种基本的功能在开箱即用的GAE上是不可能的。

回答

6

您不能在App Engine上进行该类型的子字符串搜索。原因是App Engine数据存储的构建是可扩展的,并拒绝执行它无法满足索引的任何查询。索引这样的查询几乎是不可能的,因为它需要搜索每个记录的“字段”属性的全部匹配。任何运行此查询的关系数据库都将通过执行全表扫描并单独检查每个记录来执行它 - 不可伸缩的,至少可以说。

正如你已经发现的,解决方案是使用全文索引,比如Lucene。在App Engine上有用于运行Lucene的库,例如GAELucene。这也给你适当的全文搜索的力量,而不是天真的子串匹配。

+0

尼克,感谢您的答复。数据存储可以创建单个词的索引,而不是%foo%?我的意思是,Google显然能够进行关键字搜索,如果不是类似于正则表达式的搜索。 我真正想要完成的是扫描一组关键字的食谱,所以也许我制定了我的问题很差。谢谢。 – 2009-09-30 15:41:51

+1

是的 - 你所指的是被称为“倒排索引” - 这就是Lucene使用的库。对于Python,有SearchableModel,它实现了这种模式。如果你愿意,你可以在Java中做同样的事情,但是使用Lucene可能会更好。 – 2009-09-30 16:54:15

1

tl; dr:管理您自己的多值搜索属性并对其执行等值查询。

详情: 对于那些寻找一些简单的DIY,你可以做到以下几点:

  1. 在你的实体,创建一个多值searchTerms财产。这将包含实体的可搜索项目。

  2. 将实体的可搜索文本拆分为单词。这些词将是实体唯一可搜索的部分。你可以先分开空白,或者你可以添加一些基本的词干。例如。在处理电子邮件地址时,您可能需要分别放置用户和域部分,以便可以搜索这两部分。如果你的实体更新,你需要重建这个属性。

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

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

    E.g. (使用Objectify):

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

相关问题