我阅读了this问题的答案,发现有两种方法可以在没有任何用户干预的情况下进一步缩小用户搜索查询的结果范围:
我在实现层面理解上述技术,但在概念层面不理解。我有以下问题:
感谢。
答案 0 :(得分:3)
Lucene应用过滤器的顺序是什么。
真的重要吗?如果你有n个独立的过滤器,那么总体结果将是这些过滤器运行的函数和彼此重叠的函数。
是在查询之前还是之后?
严格来说,他们携手合作。以下是IndexSearcher.java
(Lucene ver 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,之前已经讨论过。
答案 1 :(得分:1)
如果某些标准没有改变,并且在每次索引更新之间会多次重复使用,那么Filter
通常就可以了。
例如,我通常使用Filters来获取用户权限。每次索引更新后,缓存的Filter只会重新计算一次,直到下一次更新。如果你的索引不是实时的话,那就非常有效。
过滤器的另一个用例是避免BooleanQuery.TooManyClauses
例外。
答案 2 :(得分:0)
如果您在为查询附加布尔子句和使用过滤器之间犹豫不决,则可能意味着您应该使用过滤器。
过滤器优于布尔子句,因为它们不需要得分。因此,它们更快并且可以缓存(如果您经常使用相同的条件进行过滤,则非常有用)。
Lucene在查询后不应用过滤器。相反,它首先检查过滤器,以便不会得分(得分可能是昂贵的)文件,无论如何都会过滤掉。