Java Lucene中的{Filter}比{Query}快吗?

Java Lucene中的{Filter}比{Query}快吗?,java,lucene,Java,Lucene,在阅读“Lucene in Action第二版”时,我偶然发现了可用于Lucene中的结果过滤的Filter类的描述。Lucene有很多过滤器重复Query类。例如,numeriRangeQuery和numeriRangeFilter 这本书说,NRF与NRQ完全相同,但没有文档评分。这是否意味着,如果我不需要按文档字段值对文档进行评分或排序,那么从性能角度来看,我更喜欢过滤器ing而不是查询ing?如果要重用过滤器,出于缓存目的,最好使用它而不是查询。如果您不打算使用评分值或字段值,那么使用过

在阅读“Lucene in Action第二版”时,我偶然发现了可用于Lucene中的结果过滤的
Filter
类的描述。Lucene有很多过滤器重复
Query
类。例如,
numeriRangeQuery
numeriRangeFilter


这本书说,
NRF
NRQ
完全相同,但没有文档评分。这是否意味着,如果我不需要按文档字段值对文档进行评分或排序,那么从性能角度来看,我更喜欢
过滤器
ing而不是
查询
ing?

如果要重用过滤器,出于缓存目的,最好使用它而不是查询。如果您不打算使用评分值或字段值,那么使用过滤覆盖查询也是有意义的


希望这有帮助

与丹尼斯的回答相反:不,你可能不想使用过滤器,除非你要多次重复使用同一个查询

NumericRangeFilter
只是
MultiTermQueryRapperFilter
的一个子类,这意味着它本质上做了如下工作:

for each document in index:
   if document matches query:
      match[i] = 1
   else
      match[i] = 0
因此,它将在索引上以线性时间运行,而不是像普通查询那样以对数时间运行

此外,过滤器将占用更多内存(索引中每个文档占用一位内存)

如果您要一次又一次地使用同一个查询,那么您可能值得为性能/内存命中支付一次费用,并让以后的使用更快。但如果是一次性查询,几乎肯定不值得


(另外,如果要重用它,请使用
CachingWrapperFilter
,以便缓存该过滤器。)

我从Uwe Schindler那里收到了一个很好的答案,让我在这里重新发布

如果你不缓存过滤器,查询会更快,就像ContinonsCorer一样 在Lucene中有一些优化,这些优化目前不用于过滤器。 如果缓存过滤器(例如,如果您始终具有相同的访问权限),则过滤器可以 适用于特定用户的所有查询的限制)。在里面 在这种情况下,过滤器只执行一次,并进一步缓存 请求,然后与查询结果集相交

如果您只想随机“过滤”,例如,通过一个可变的数值范围 就像地理搜索中的边界框一样,使用查询,查询在大多数情况下都是有效的 案例速度更快(例如范围查询和类似的东西-称为多项查询 -在内部也由相同的位集算法实现,如 过滤器-事实上,它们只是由记分器impl包装的过滤器。但是 将查询和“筛选”查询放在一起的记分器 (ConnectionsCorer)通常比应用 搜索后过滤。这可能会有一些改进,但总的来说 过滤器是Lucene中不再需要的东西,所以 是否已经有一些方法使过滤器和查询相同,以及 相反,您还可以缓存非评分查询。这会有很多好处 代码更简单

如果使用Lucene 4.0,过滤器可以带来巨大的速度提升 插入IndexReader的顶部,以便在评分前过滤文档, 但这还没有实现(参见 )-我正在努力。我们 还可以使过滤器随机访问(因为它们是位集,所以很容易),这 还可以改进后查询过滤。但我也会这样做 查询部分随机访问,如果它们能够支持的话(比如 仅基于FieldCache)

Uwe

我发现这似乎建议使用过滤器而不是查询。直觉上,这对我来说更有意义,因为他们几乎应该做同样的事情,唯一的区别是分数中没有使用过滤器

考虑使用过滤器。它可以更有效地限制 使用缓存的位集筛选器而不是 而不是使用查询子句。这对于限制尤其如此 匹配大量文档的大型索引。过滤器是 通常用于将结果限制为一个类别,但在许多情况下可能会 cases可以用来替换任何查询子句。两者之间的一个区别 使用查询和筛选器是因为查询对 当过滤器不存在时进行评分


数据库是本地的还是在不同的服务器上?数据库存储在本地。在一些服务器上,我们也有SSD驱动器。