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

Bol*_*ine 1 java lucene elasticsearch

我在理解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") );
Run Code Online (Sandbox Code Playgroud)

问题:

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

Val*_*Val 5

主要区别在于它们的执行方式.这里的关键字是bitset.简单地说,bool过滤器利用位集,而and过滤器则不利用.

使用bool过滤器时,会创建位集,然后进行AND/OR,以便找出匹配的文档.

当使用and过滤器时,ES只是逐个扫描文档列表,包括或不包括它,具体取决于它是否与过滤器匹配.

不用说,bool过滤器比一个过滤器更快and.然而,并非总是如此.有些情况下,你仍然要喜欢的情况andbool:使用地理过滤器,脚本过滤和数字范围过滤器,即当使用这些过滤器,ES具有反正遍历所有文档时.

但是,所有这些仅适用于ES pre-2.0,从2.0开始,and/ orfilters将实现为bool,并且查询DSL将被彻底检修,因此查询和过滤器之间不再存在任何差异.

有关更深入的信息,您可以在这篇名为"所有关于ES过滤器位集"的博文中阅读细节.

所以你正在做的事情还可以,但更简洁的选择就是简单地使用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"));
Run Code Online (Sandbox Code Playgroud)