2009-12-30 72 views
11

我想在我的离线(android)应用程序中执行全文搜索来搜索用户生成的笔记列表。像谷歌一样的全文搜索

我想它表现得就像谷歌(因为大多数人已经习惯查询到谷歌)

我最初的要求是:

  • 快速:像谷歌或尽可能快,有100000个文件,每个200个字。
  • 搜索两个单词只应返回包含两个单词(不只是一个单词)的文档(除非使用OR运算符)
  • 不区分大小写(又名:规范化):如果我有单词“Hello”搜索它应该匹配的'hello'。
  • 变音符号不敏感:如果我有'así'这个词,搜索'asi'应该匹配。在西班牙语中,很多人不正确地要么不放置变音符号,要么不能正确放置它们。
  • 停用词的消除:为了不会有像'和'这样的巨大索引毫无意义的词,''或'for'根本不应该被索引。
  • 字典替换(又名:词干):类似的词应该被索引为一个。例如,'饥饿'和'饥饿'的例子应该用'饥饿'代替。
  • 短语搜索:如果我有文字'Hello world!'搜索''world hello''不应该匹配它,而是应该匹配''hello world''的搜索。
  • 如果未指定字段(不仅仅是默认字段),则搜索所有字段(在多字段文档中)
  • 在键入时自动完成搜索结果以提供热门搜索。 (就像谷歌建议)

我该如何配置一个全文搜索引擎尽可能像谷歌一样行事?

(我在开源的Java,特别是Lucene的最感兴趣)

+1

如果你指向Lucene,它可以处理许多开箱即用且可扩展的问题,那么你可以针对你遇到的问题具体说明一下吗? – 2009-12-30 00:38:41

+0

你在找什么? – SLaks 2009-12-30 00:39:15

+0

您确实意识到Google采用了http://en.wikipedia.org/wiki/Query_expansion并利用了其他人的搜索记录。如果每个搜索“电脑鼠标”的人最终都会点击yahoo.com(制作它),那么随着时间的推移,yahoo.com将成为“电脑鼠标”的首个搜索结果。 – 2009-12-30 00:44:27

回答

14

我认为Lucene可以满足您的要求。您还应该考虑使用Solr,它具有相似的功能并且更易于设置。

我将分别讨论每个需求,使用Lucene。我相信Solr有类似的机制。

  • 快速:像谷歌或尽可能快的,有100000页的文件,每个200百个字。

这是既为Lucene和Solr的一个合理的索引的大小,以数十每个查询毫秒使检索。

  • 搜索两个词应该只返回包含两个词(不只是一个字)的文件(除非OR运算符时)

你可以做到这一点使用BooleanQuery与在Lucene中默认为MUST

  • 不区分大小写(又名:标准化):

    接下来的四个要求,可以通过自定义一个Lucene Analyzer进行处理。如果我有字“你好”,我搜索“你好”它应该比赛。

LowerCaseFilter可以用于此目的。

  • 语音标记不敏感:如果我有一句话“ASI”的搜索“ASI”应该匹配。在西班牙语中,很多人不正确地要么不放置变音符号,要么不能正确放置它们。

这需要Unicode规范化,然后进行分隔符清除。您可以为此构建自定义分析器。

  • 停用词消除:要没有像一个巨大的指数意义的话“和”,“的”或“对”不应该在所有的索引。

一个StopFilter消除在Lucene的停止词。

  • 字典替换(又名:词干):类似的词应该被索引为一个。例如,'饥饿'和'饥饿'的例子应该用'饥饿'代替。

lucene有很多Snowball Stemmers。其中之一可能是适当的。

  • 短语搜索:如果我有文本“世界,你好!'搜索'世界你好''不应该匹配它,但''你好世界''的搜索应该匹配。

这是由Lucene的PhraseQuery专门的查询覆盖。

正如您所看到的,Lucene涵盖了所有必需的功能。为了获得更全面的图片,我建议书Lucene in Action,The Apache Lucene WikiThe Lucid Imagination Site

2

Google Search Appliance。或者,正如评论所说,使用Lucene就像你已经提到过的那样。

+1

谷歌搜索设备不适合在离线Android应用程序中搜索数据。 – 2012-09-03 23:18:25

+2

我发布我的答案后7小时添加了Android位。 3年后,搜索格局发生了巨大变化。 – 2012-09-04 17:51:59

3

很多这些行为是Lucene默认的。第一次(包括所有方面)不是,但你可以通过设置默认的操作迫使这种行为:

MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer()); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 

我知道,项目2,4和6是可能的,并且IIRC,它们发生在默认情况下。我不确定项目3和5,但Lucene提供了大量的自定义选项,因此我建议对数据实施概念验证,以确定它是否也符合这些要求。

0

除非你购买了搜索引擎,否则你有Lucene,Nutch,Apache Solr和其他一些搜索引擎。

0

HyperSQL是一个纯Java的SQL实现,可以像SQLite一样轻松地运行。您可以使用全文功能并查询重新创建轮子,但正如其他评论者指出的,现有的实施可能是最好的。