0

我正在使用 Lucene 3.6.1

我最初有一个查询,对于给定的“真爱”输入,我会创建一个这样的查询:

+(+content:true +content:love) 
+(title:"true love"^3.0 ((title:true title:love)^2.0) 
(subTitle:true subTitle:love)) 
title_starts_with:true love*^3.0 
+showToPublic:y

查询时间为:

  • 应用程序启动后的第一次查询(无预热):250-300 毫秒

  • 后续查询:35-40 ms

阅读Lucene 的搜索速度提示页面,我发现他们建议尽可能使用过滤器:

考虑使用过滤器。使用缓存位集过滤器而不是使用查询子句将结果限制到索引的一部分会更有效。对于匹配大量索引的大量文档的限制尤其如此。过滤器通常用于将结果限制为一个类别,但在许多情况下可用于替换任何查询子句。使用查询和过滤器的一个区别是查询对分数有影响,而过滤器没有。

因此,我删除了 +showToPublic:y查询的一部分,并添加了一个TermsFilter,如下所示:

TermsFilter showToPublicFilter =  new TermsFilter();            
showToPublicFilter.addTerm(new Term("showToPublic","y"));
indexSearcher.search(booleanQuery, showToPublicFilter, collector);

我注意到的是,现在第一个查询要快得多,但后续查询比以前慢很多:

  • 应用程序启动后的第一次查询(无预热):200-220 毫秒

  • 后续查询:190-200 ms

我觉得这很奇怪,因为 TermsFilter 的 JavaDoc 说它非常适合我目前的情况:

为与添加到此类的任何术语匹配的文档构造一个过滤器。与 RangeFilter 不同,它可用于过滤不一定按顺序排列的多个术语。一个示例可能是来自数据库查询结果的主键集合,或者可能是最终用户选择的“类别”标签。作为过滤器,这比等效查询(具有许多“应该”术语查询的 BooleanQuery)快得多

我也尝试过使用FieldValueFilter(因为我的“showToPublic”字段有“y”或没有值):

FieldValueFilter showToPublicFilter =  new FieldValueFilter("showToPublic", false);  
indexSearcher.search(booleanQuery, showToPublicFilter, collector);

但是有了这个,我根本没有得到任何结果(当然更快)。

所以我的问题是:

  • 这是正常行为吗,即不能保证过滤器总是比等效的布尔查询快?
  • 是否还有其他一些我应该使用的过滤器(我已经浏览了所有这些过滤器,对我来说,似乎 TermsFilter 和/或 FieldValueFilter 是唯一适用于这种情况的过滤器)?
  • 为什么 FieldValueFilter 在这里不起作用?
4

1 回答 1

2

您可以尝试使用CachingWrapperFilter包装另一个过滤器的结果并将其缓存。重复使用它。

每次使用 FilteredQuery 进行搜索时都会调用底层的 Filter.getDocIdSet(),因此如果要重复使用查询并且过滤结果不改变,建议使用缓存过滤器。

如果您使用缓存机制,您可能会发现性能有所提高。

于 2013-03-06T16:28:22.403 回答