2

我阅读了这个问题的答案,发现有两种方法可以在没有任何用户干预的情况下进一步缩小用户搜索查询的范围:

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

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

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

谢谢。

4

3 回答 3

3

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 查询字符串注入。在某些情况下,性能影响可以忽略不计,并且首选过滤器选项,因为过滤结果集比添加查询元素更容易。

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

看到这个问题,之前已经讨论过了。

于 2013-01-21T11:24:02.240 回答
1

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

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

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

于 2013-01-21T15:00:46.787 回答
0

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

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

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

于 2013-01-21T14:59:39.260 回答