Elastic Search中And filter和Bool过滤器的区别是什么?

时间:2015-08-21 12:45:04

标签: java elasticsearch lucene

我很难理解Bool过滤器与弹性搜索中的And过滤器之间的区别。

上下文:说我的文档有字段:X,Y,Z。

每个字段可以有多个值。

目标

我想在以下意义上向弹性搜索发送查询:(X = valueX1或X = valueX2)AND(Y = valueY1或Y = valueY2 OR ..)AND(Z = valueZ1 OR Z = valueZ2 OR。 ..)。

尝试

这就是我这样做的方式:

BoolFilterBuilder mainClaus = FilterBuilders.boolFilter();
FilterBuilder filterBuilder = mainClaus;

BoolFilterBuilder xClaus = FilterBuilders.boolFilter();
BoolFilterBuilder yClaus = FilterBuilders.boolFilter();
BoolFilterBuilder zClaus = FilterBuilders.boolFilter();

mainClaus.must(xClaus);
mainClaus.must(yClaus);
mainClaus.must(zClaus);

//Return a document if it has at least one of those values.
xClaus.should( FilterBuilders.termFilter("X", "valueX1") );
xClaus.should( FilterBuilders.termFilter("X", "valueX2") );
xClaus.should( FilterBuilders.termFilter("X", "valueX3") );

//Return a document if it has at least one of those values.
yClaus.should( FilterBuilders.termFilter("Y", "valueY1") );
yClaus.should( FilterBuilders.termFilter("Y", "valueY2") );
yClaus.should( FilterBuilders.termFilter("Y", "valueY3") );

//Return a document if it has at least one of those values.
zClaus.should( FilterBuilders.termFilter("Z", "valueZ1") );
zClaus.should( FilterBuilders.termFilter("Z", "valueZ2") );
zClaus.should( FilterBuilders.termFilter("Z", "valueZ3") );

问题

  • 我的方法是否正确?
  • Bool过滤器和And过滤器之间的区别是什么?

2 个答案:

答案 0 :(得分:5)

主要区别在于它们的执行方式。此处的关键字为 bitset 。简而言之,bool过滤器会利用位集,而and过滤器则不会。

使用bool过滤器时,会创建位集,然后将AND / OR一起编辑,以便找出匹配的文档。

当使用and过滤器时,ES会逐个扫描文档列表,是否包含文档,具体取决于是否与过滤器匹配。

毋庸置疑,bool过滤器比and过滤器快得多。然而,并非总是如此。在某些情况下,您仍然希望and优先于bool:当使用地理过滤器,脚本过滤器和数值范围过滤器时,即使用这些过滤器时,ES必须遍历所有文档。< / p>

但是,所有这些仅适用于ES pre-2.0,因为starting in 2.0and / or过滤器将实现为bool,查询DSL将是完全彻底检查,以便查询和过滤器之间不再有任何区别。

有关更深入的信息,您可以在这篇名为"All about ES filter bitsets"

的博客文章中阅读细节。

所以你正在做的事情还可以,但更简洁的选择就是must三个terms过滤器,就像这样:

BoolFilterBuilder mainClaus = FilterBuilders.boolFilter();
mainClaus.must(FilterBuilders.termsFilter("X", "valueX1", "valueX2", "valueX3"));
mainClaus.must(FilterBuilders.termsFilter("Y", "valueY1", "valueY2", "valueY3"));
mainClaus.must(FilterBuilders.termsFilter("Z", "valueZ1", "valueZ2", "valueZ3"));

答案 1 :(得分:0)

这里不应该使用布尔过滤器,而是应该进行多匹配查询。 因为你正在学习一个变量&#39; X&#39;有三个不同的值,类似下面的代码将是一个更好的方法。

String [] params = {'valueX1','valueX3','valueX3'}

queryBuilder =  QueryBuilders.multiMatchQuery('X', params);

然后可以将此queryBuilder添加为更大的“必须”的一部分。查询可以比较所有三个变量X,Y和Z的位置。

您可以在此处详细了解多匹配查询。 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html