Lucene TermsFilter加速第一次查询,减慢后续查询

时间:2013-03-06 12:38:37

标签: performance filter lucene

我正在使用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 ms

  • 后续查询:35-40毫秒

阅读Lucene's Search Speed Tips page我发现他们建议尽可能使用过滤器:

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

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

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

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

  • 应用程序之后的第一次查询(没有预热):200-220 ms

  • 后续查询:190-200 ms

我发现这很奇怪,因为TermsFilter的JavaDoc对我目前的情况来说是理想的:

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

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

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

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

所以我的问题是:

  • 是这种正常行为,即过滤器不能保证总是比等效的布尔查询更快吗?
  • 我应该使用其他一些过滤器(我已经仔细查看过它们,对我而言,似乎是TermFilter和/或FieldValueFilter是唯一适用于这种情况的过滤器)?
  • 为什么FieldValueFilter不在这里工作?

1 个答案:

答案 0 :(得分:2)

您可以尝试使用CachingWrapperFilter来包装其他过滤器的结果并对其进行缓存。重复使用它。

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

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