【问题标题】:Filters vs silently appending a criteria to a user search query in Lucene过滤器与默默地将条件附加到 Lucene 中的用户搜索查询
【发布时间】:2013-01-22 20:13:34
【问题描述】:

我阅读了this 问题的答案,发现有两种方法可以进一步缩小用户搜索查询的结果范围,而无需任何用户干预:

  1. 通过静默修改查询
  2. 应用 Lucene 过滤器

我在实现层面了解上述两种技术,但在概念层面不了解。我有以下问题:

  1. Lucene 应用过滤器的顺序是什么。是在查询之前还是之后?如果我按名字去,我想应该是之后。
  2. 何时使用一种技术而不是另一种?
  3. 在没有功能差异的情况下,上述两种技术之间是否存在性能差异?
  4. 当文档具有与之关联的用户权限并且用户在搜索结果中只能看到他/她的文档时,哪种技术更合适?

谢谢。

【问题讨论】:

    标签: lucene lucene.net


    【解决方案1】:

    Lucene 应用过滤器的顺序是什么。

    这真的很重要吗?如果您有 n 个独立的过滤器,则总体结果将是这些过滤器在彼此之上运行 AND 函数的乘积。

    是在查询之前还是之后?

    严格来说,它们是携手合作的。这是IndexSearcher.java(Lucene 3.4 版)的摘录

    while (true) {
      if (scorerDoc == filterDoc) {
        // Check if scorer has exhausted, only before collecting.
        if (scorerDoc == DocIdSetIterator.NO_MORE_DOCS) {
          break;
        }
        collector.collect(scorerDoc);
        filterDoc = filterIter.nextDoc();
        scorerDoc = scorer.advance(filterDoc);
      } else if (scorerDoc > filterDoc) {
        filterDoc = filterIter.advance(scorerDoc);
      } else {
        scorerDoc = scorer.advance(filterDoc);
      }
    }
    

    我对这段代码的理解是过滤器/记分器迭代器都向前推进,如果过滤器在记分器之前,则使用记分器,反之亦然。

    何时使用一种技术而不是另一种?

    在没有功能差异的情况下,上述两种技术是否存在性能差异?

    我通常更喜欢在查询中添加额外的位,因为我相信这比查询后过滤更快(即使您使用QueryWrapperFilter)。但是您需要确保客户无法进行 Lucene 查询字符串注入。在某些情况下,性能影响可以忽略不计,因此首选过滤器选项,因为过滤结果集比添加查询元素更容易。

    当文档具有与之关联的用户权限并且用户在搜索结果中只能看到他/她的文档时,哪种技术更合适?

    this question,之前已经讨论过了。

    【讨论】:

      【解决方案2】:

      如果某些标准没有改变并且会在每次索引更新之间重复使用多次,那么Filter 通常是要走的路。

      例如,我通常使用过滤器来获取用户权限。每次索引更新后,缓存的过滤器只会重新计算一次,直到下一次更新。如果您的索引不是实时的,这会非常有效。

      过滤器的另一个用例是避免BooleanQuery.TooManyClauses 异常。

      【讨论】:

      • 提示:你可以调用BooleanQuery.setMaxClauseCount(count)(静态方法)来增加这个限制。
      • 是的,但是您仍然停留在 Int32.MaxValue-1,并且如果可能的话,最好使用过滤器来避免将最大子句计数设置为一个巨大的值,因为在这种情况下,过滤器将肯定会更有效率。
      【解决方案3】:

      如果您在将布尔子句附加到查询和使用过滤器之间犹豫不决,这可能意味着您应该使用过滤器。

      过滤器比布尔子句更好,因为它们不需要评分。因此,它们更快并且可以被缓存(如果您经常使用相同的条件进行过滤,这将非常有用)。

      Lucene 不会在查询后应用过滤器。相反,它首先检查过滤器,以免对无论如何都会被过滤掉的文档进行评分(评分可能很昂贵)。

      【讨论】:

      • 谁能解释一下-1?
      • +1 用于提供有关过滤器的更多详细信息。你关于得分的最后一句话对我来说是合乎逻辑的。您能否向我指出(如果您知道的话)任何可以帮助我了解更多有关过滤器的在线参考资料。
      • 你能评论我的回答吗?从我看过的代码来看,过滤和评分似乎可以互换发生,具体取决于具体情况。附:否决票不是我的。
      • @Arnand 我不知道好的资源。了解它是如何工作的最好方法可能是详细了解 IndexSearcher.search(Query, Filter, int)
      • @mindas 实际上,有几种策略(参见svn.eu.apache.org/repos/asf/lucene/dev/trunk/lucene/core/src/…)可以通过跳跃式方法或将过滤器用作随机访问位集来将查询与过滤器相交。在这两种情况下,只有当文档与过滤器匹配时才会执行评分,这就是为什么我说过滤发生在查询评估之前,尽管并不完全正确。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多