Indexing Lucene mutli语言分析器/索引方法

Indexing Lucene mutli语言分析器/索引方法,indexing,multilingual,lucene,analyzer,Indexing,Multilingual,Lucene,Analyzer,我有一个支持建议服务的Lucene索引。当用户在搜索框中键入内容时,它会通过SUGGESTION_字段查询索引。SUGGESTION_字段中的每个条目都可以是许多受支持的语言之一,并且每个条目都使用适当的特定于语言的分析器进行存储。为了知道使用了什么analyzer,每个条目都有第二个字段,用于存储区域设置。因此,在查询过程中,我可以使用下面的代码使用适当的分析器执行特定于语言的查询 QueryParser parser = new QueryParser(Version.LUCENE_33,

我有一个支持建议服务的Lucene索引。当用户在搜索框中键入内容时,它会通过SUGGESTION_字段查询索引。SUGGESTION_字段中的每个条目都可以是许多受支持的语言之一,并且每个条目都使用适当的特定于语言的分析器进行存储。为了知道使用了什么analyzer,每个条目都有第二个字段,用于存储区域设置。因此,在查询过程中,我可以使用下面的代码使用适当的分析器执行特定于语言的查询

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.. 
"SUGGESTION_FIELD_en:" + queryString + " AND SUGGESTION_FIELD_fr:" + queryString + " AND SUGGESTION_FIELD_es:" + queryString
对每个字段使用不同的分析器(使用PerfielDanalyzerRapper),然后使用更复杂的查询字符串进行查询,以便:

SUGGESTION_FIELD_en, SUGGESTION_FIELD_fr, SUGGESTION_FIELD_es etc.. 
"SUGGESTION_FIELD_en:" + queryString + " AND SUGGESTION_FIELD_fr:" + queryString + " AND SUGGESTION_FIELD_es:" + queryString

如果您认为:)

您的查询是这样的:(sugField:queryString1和locale:loc1)或(sugField:queryString2和locale:loc2)或。。。。这是一个顶级布尔查询,其下级布尔查询添加了occurs=SHOULD,其中每个下级查询都有occurs=MUST。queryString1、queryString2等是具有相同输入的不同语言分析器的输出,即用户输入的字符串

每个次级查询都涉及索引中罕见的强制性术语(来自您的查询字符串),Lucene从一开始就知道这一点(它知道索引中每个术语的文档总数),因此它将首先通过queryString约束结果,然后再将其与区域设置术语相交。无论索引有多大,这都是非常有效的


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

从您指定的内容来看,这似乎不是一项很大的工作——为什么不将您需要的所有区域设置一起使用呢?谢谢。因为我不相信当指数上升时它会运行得更快。你的权利,虽然这不是很多工作。不幸的是,虽然我使用的是一个没有太多数据的测试数据库,所以我不能确定当索引最终在生产环境中变得非常大时,哪一个会更好。所以我对人们的观点感兴趣:)你的查询应该是这样的:sugField:queryString和(locale:loc1或locale:loc2或…)。这是一个布尔查询,由TermQueries组成,其中一个术语为必填项。这个术语在索引中也很少见,Lucene从一开始就知道这一点(它检查每个给定术语的总文档数),因此它将知道首先通过queryString约束结果,然后再与区域设置术语相交。无论索引有多大,这都将非常有效。@Marko Topolnik感谢您的回复。不幸的是,(单个查询的)这种方法不起作用,因为我需要在查询sugField时选择一个语言分析器。因此,当布尔:sugg AND(loc或loc或loc…)有效地查询索引的正确部分时,它为每个部分应用相同的覆盖层分析器。这不是我想要的。这就是为什么我上面的sol#1使用了多个调用(每个区域设置一个),这样我每次都可以应用相应的分析器的原因。谢谢@Marko Topolnik,我认为这是一个很好的解决方案。使用未分析的查询对Lucene进行一次调用,并事先单独进行所有分析。我喜欢。我以前从未进行过手动分析(在编写器或查询解析器之外)。我认为这方面的最高评分答案是正确的程序?:)实际上,Lucene 3.5中的那个不推荐的API使用。只是,我会将属性提取到一个局部变量,而不是在每次迭代中再次获取它,如。