java - 向查询短语添加单词应在 Lucene 中过滤结果

标签 java lucene

如果可能,我会悬赏 +100 这个问题,即使它已经被回答并接受

我正在使用 Lucene 3.2,这是我的索引和代码中的内容:

  • 每个索引文档超过 10 个字段。
  • OR 查询短语中的操作数(即:“my lucene search”变为“my OR lucene OR search”)。
  • MultiFieldQueryParser,所有字段中均包含 Occur.SHOULD
  • 包含所有其他字段的特定默认字段(如本解决方案中建议的 How to do a Multi field - Phrase search in Lucene? )。

我想要达到什么目的?一种类似 Google 的搜索,让我解释一下:

  • 在所有字段中搜索
  • 得分结果(特定领域的提升等)
  • 向查询短语添加单词应该过滤结果

除了最后一个方面之外,我已经达到了各个方面。我的问题如下:

  • 如果我仅在包含所有其他字段的默认字段中进行搜索,则不会获得得分较高的结果
  • 仅使用 AND 操作数进行搜索时,我得到的结果过于过滤,只能得到在一个字段中包含整个查询短语的结果。
  • 仅使用 OR 操作数进行搜索对于查询中只有一个单词来说是完美的,但是当向查询短语中添加更多单词时,结果会显着增加,而不是被过滤(就像 Google 所做的那样)。
  • 我不知道如何从一个查询中过滤另一个查询

这是我对查询解析器的实际调用:

MultiFieldQueryParser.parse(
    Version.LUCENE_31,
    OrQueryWords, //query words separated with OR operand
    searchFields, //String[] searchFields; // all fields
    occurs, //Occur[] occurs; {Occur.SHOULD, Occur.SHOULD, etc..}
    getFullTextSession().getSearchFactory().getAnalyzer(Product.class)
);

此查询的 toString() 打印如下内容:

(field1:"word1 word2" (field1:word1 field1:word2)) (field2:"word1 word2" (...)) etc.

现在我正在尝试添加默认字段(包含所有其他字段的字段),其中查询词以 AND 操作数和 Occur.MUST 分隔:

MultiFieldQueryParser.parse(
    Version.LUCENE_31,
    AndQueryWords, //query words separated with AND operand
    new String[] {"defaultField"},
    new Occur[] {Occur.MUST},
    getFullTextSession().getSearchFactory().getAnalyzer(Product.class)
);

此查询的 toString() 打印以下内容:

+(default:"word1 word2" (+default:word1 +default:word2))

如何将两个查询相交?还有其他解决办法吗?

最佳答案

我不确定您到底想要实现什么,因此我将向您提供一些有关如何在处理多字段多术语查询时自定义评分的提示。

两个查询的交集

您似乎对默认字段结果集上的合取查询以及所有字段评分上的析取查询感到满意。通过使用后者作为主要查询并使用前者作为过滤器,您可以两全其美。

例如:

Query mainQuery, filterQuery;

BooleanQuery query = new BooleanQuery();

// add the main query for scoring
query.add(mainQuery, Occur.SHOULD);

// prevent the filter query to participate in the scoring
filter.setBoost(0);
// make the filter query required
query.add(filterQuery, Occur.MUST);

最少应匹配子句

如果对所有子句进行 AND 运算的限制性太大,而对所有子句进行 OR 运算的限制性不够,那么您可以通过设置 minimum number of SHOULD clauses that must match 在两者之间做一些事情。以便文档出现在结果集中。

那么困难的部分是找到正确的公式来计算必须匹配最佳用户体验的最少 SHOULD 子句数量。

例如,假设您希望 3/4 的 SHOULD 子句的 ceil 匹配。从两个子句查询开始,添加最多 5 个子句将产生以下结果数量演变。

  • 2 个术语 => ceil(2 * 3/4) = 2:所有子句必须匹配
  • 3 个术语 => ceil(3 * 3/4) = 3: 3/4 个子句必须匹配(需要新子句,更少结果)
  • 4 个术语 => ceil(4 * 3/4) = 3:3/4 个子句必须匹配(其中一个子句是可选的,更多结果)
  • 5 个术语 => ceil(5 * 3/4) = 4:4/5 个子句必须匹配(结果可能更多,也可能更少,具体取决于新术语与前 4 个术语的共现情况)<

无论如何,有了这个特性,随着子句数量的增加,结果数量减少的唯一方法就是使用纯粹的联合查询。

关于java - 向查询短语添加单词应在 Lucene 中过滤结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9499122/

相关文章:

java - 编译和部署自定义 Solr 请求处理程序

java - Solr:结合 EdgeNGramFilterFactory 和 NGramFilterFactory

java - 如何通过命令提示符访问Java API方法?

java - 如果为 null,则 TObjectIntMap.get() 返回 0

java - 将元组数组发送到准备好的语句

Java Spring Boot Web 应用程序 : Handling 404 Exception

search - Lucene.Net 是否适合作为频繁变化内容的搜索引擎?

java - Apache Solr 6.6.1 乌尔都语语言的数字映射

java - 在执行搜索之前操作 Lucene 查询

java - java中计算一个数除以另一个数的次数并打印出来