【问题标题】:Lucene mutli-language analyzer/index approachLucene 多语言分析器/索引方法
【发布时间】:2012-04-17 02:59:39
【问题描述】:

我有一个支持建议服务的工作 Lucene 索引。当用户在搜索框中输入内容时,它会通过 SUGGESTION_FIELD 查询索引。 SUGGESTION_FIELD 中的每个条目都可以是许多受支持的语言之一,并且每个条目都使用适当的语言特定分析器进行存储。为了知道使用了什么分析器,每个条目都有第二个字段来存储 LOCALE。因此,在查询期间,我可以说类似下面的代码来使用适当的分析器进行特定于语言的查询

QueryParser parser = new QueryParser(Version.LUCENE_33, SUGGESTION_FIELD, getLangaugeAnalyzer(locale));
return searcher.search(parser.parse("SUGGESTION_FIELD:" + queryString + " AND LOCALE:"
                + locale), 100);

工作....但是现在客户希望能够同时使用多种语言进行搜索。

我的问题:考虑到建议服务需要非常快,最快的查询解决方案是什么?...

溶胶。 #1。最简单的解决方案似乎是;多次查询。每个区域设置一次,从而每次应用相应的语言分析器。最后以某种合理的方式附加每个查询的结果

溶胶。 #2。或者,我可以使用每个语言环境的列重新索引,这样:

SUGGESTION_FIELD_en, SUGGESTION_FIELD_fr, SUGGESTION_FIELD_es etc.. 

对每个字段使用不同的分析器(使用 PerFieldAnalyzerWrapper),然后使用更复杂的查询字符串进行查询,例如:

"SUGGESTION_FIELD_en:" + queryString + " AND SUGGESTION_FIELD_fr:" + queryString + " AND SUGGESTION_FIELD_es:" + queryString

如果你认为你可以帮忙:)

【问题讨论】:

  • 从您指定的内容来看,这似乎不是很多工作 - 为什么不直接 OR 一起使用您需要的所有语言环境?
  • 谢谢。因为我不相信当索引扩大时它会运行得更快。你的权利,虽然它不是很多工作。不幸的是,虽然我正在使用一个没有很多数据的测试数据库,所以我不能确定当索引最终在生产环境中变得非常大时哪个会更好。所以我对人们的意见很感兴趣:)
  • 您的查询将是这样的:sugField:queryString AND (locale:loc1 OR locale:loc2 OR ...)。这是一个由 TermQueries 组成的 BooleanQuery,其中一个是强制性的。这个词在索引中也很少见,Lucene 在一开始就知道这一点(它检查给定的每个词的总文档数),因此它会知道首先通过 queryString 约束结果,然后再将其与区域设置词相交。无论您的索引有多大,这都会非常有效。
  • @Marko Topolnik 感谢您的回复。不幸的是,这种方法(单个查询)不起作用,因为我在查询 sugField 时需要选择语言分析器。因此,当 boolean: sugg AND (loc OR loc OR loc ...) 有效地查询索引的正确部分时,它对每个部分应用相同的全面分析器。这不是我想要的。这就是为什么我上面的 sol #1 使用了多个调用(每个语言环境一个),以便我每次都可以应用相应的分析器

标签: indexing multilingual lucene analyzer


【解决方案1】:

您的查询将是这样的: (sugField:queryString1 AND locale:loc1) OR (sugField:queryString2 AND locale:loc2) OR .... 这是一个顶级 BooleanQuery 与从属 BooleanQueries 添加发生=SHOULD,其中每个从属查询都有其条款与发生=MUST。 queryString1、queryString2 等是来自不同语言分析器的输出,具有相同的输入,即用户输入的字符串。

每个从属查询都涉及索引中很少见的强制性术语(来自您的查询字符串),Lucene 在一开始就知道这一点(它知道索引中每个术语的总文档数),因此它首先将结果限制为查询字符串,然后另外将其与语言环境术语相交。无论您的索引有多大,这都会非常有效。

对于不同的分析器,我建议您不要使用 QueryParser,而是以编程方式创建整个查询。当您不手动输入查询时,这是一个很好的一般建议,在您的情况下,这是获得分析方面控制权的唯一方法。通过每个特定于语言的分析器运行您的查询字符串,并将它们的输出标记作为 TermQueries 添加到从属 BooleanQueries。

【讨论】:

  • 谢谢@Marko Topolnik 我认为这是一个很好的解决方案。使用非分析查询对 Lucene 进行一次调用,并事先分别进行所有分析。我喜欢。我以前从未做过手动分析(在编写器或查询解析器之外)。我认为这个stackoverflow.com/questions/6334692/… 上评分最高的答案是正确的程序吗? :)
  • 实际上,在 Lucene 3.5 中已弃用的 API 使用 less-upvoted answer。只是,我会将属性提取到本地 var,而不是在每次迭代中再次获取它,例如 here
猜你喜欢
  • 2011-07-13
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多