【问题标题】:Is {Filter}ing faster than {Query}ing in Lucene?Lucene 中的 {Filter} 比 {Query} 快吗?
【发布时间】:2011-09-21 16:26:33
【问题描述】:

在阅读“Lucene in Action 2nd edition”时,我遇到了Filter 类的描述,这些类可用于 Lucene 中的结果过滤。 Lucene 有很多过滤器重复Query 类。例如,NumericRangeQueryNumericRangeFilter

这本书说NRFNRQ 完全相同,但没有文档评分。这是否意味着如果我不需要评分或按文档字段值对文档进行排序,从性能的角度来看,我应该更喜欢Filtering 而不是Querying?

【问题讨论】:

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

标签: java lucene


【解决方案1】:

如果过滤器将被重用,由于缓存的目的,使用它而不是查询是明智的。如果您不打算使用评分或字段值,那么在查询上使用过滤器也是有意义的。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    与 Dennis 的回答相反:不,您可能不想使用过滤器,除非您要多次重复使用相同的查询。

    NumericRangeFilter 只是MultiTermQueryWrapperFilter 的子类,这意味着它本质上是这样的:

    for each document in index:
       if document matches query:
          match[i] = 1
       else
          match[i] = 0
    

    因此它将在您的索引上以线性时间运行,而不是像普通查询那样以对数时间运行。

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

    如果您要一遍又一遍地使用相同的查询,那么为性能/内存付出一次代价并让以后的使用速度更快可能是值得的。但如果是一次性查询,那几乎肯定不值得。

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

    【讨论】:

      【解决方案3】:

      我从 Uwe Schindler 那里得到了很好的回答,让我在这里重新发布。

      如果你不缓存过滤器,查询会更快,因为 ConjunctionScorer 在 Lucene 中有优化,目前还没有用于过滤器。 过滤器很好,如果你缓存它们(例如,如果你总是有相同的访问权限 特定用户的所有查询的限制)。在 在这种情况下,过滤器只执行一次并被进一步缓存 请求,然后与查询结果集相交。

      如果你只想随机“过滤”,例如通过可变数值范围 就像地理搜索中的边界框一样,使用查询,查询在大多数 案例更快(例如范围查询和类似的东西 - 称为 MultiTermQueries - 在内部也由相同的 BitSet 算法实现,如 过滤器 - 实际上它们只是被记分器-impl 包装的过滤器)。但是 将查询和您的“过滤器”查询组合在一起的记分器 (ConjunctionScorer) 通常比应用 搜索后过滤。这可能会有所改进,但总的来说 过滤器是 Lucene 中不再需要的东西,所以有 已经有一些方法可以使过滤器和查询相同,并且 而是能够缓存非评分查询。这会让很多 代码更容易。

      过滤器可以在 Lucene 4.0 中带来巨大的速度提升,如果它们是 插入 IndexReader 以在 评分之前过滤文档, 但这还没有实现(见 https://issues.apache.org/jira/browse/LUCENE-3212) - 我正在努力。我们 也可以使过滤器随机访问(很容易,因为它们是位集),这 还可以改进查询后过滤。但我也会做 查询部分随机访问,如果他们可以支持的话(比如查询 仅基于 FieldCache)。

      呜呜

      【讨论】:

        【解决方案4】:

        我在http://wiki.apache.org/lucene-java/ImproveSearchingSpeed 中发现了这个,它似乎建议使用过滤器而不是查询。直觉上这对我来说更有意义,因为他们几乎应该做同样的事情,唯一的区别是分数中没有使用过滤器。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-30
          • 2018-11-08
          • 2021-10-14
          • 1970-01-01
          相关资源
          最近更新 更多