我很难理解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") );
问题:
答案 0 :(得分:5)
主要区别在于它们的执行方式。此处的关键字为 bitset 。简而言之,bool
过滤器会利用位集,而and
过滤器则不会。
使用bool
过滤器时,会创建位集,然后将AND / OR一起编辑,以便找出匹配的文档。
当使用and
过滤器时,ES会逐个扫描文档列表,是否包含文档,具体取决于是否与过滤器匹配。
毋庸置疑,bool
过滤器比and
过滤器快得多。然而,并非总是如此。在某些情况下,您仍然希望and
优先于bool
:当使用地理过滤器,脚本过滤器和数值范围过滤器时,即使用这些过滤器时,ES必须遍历所有文档。< / p>
但是,所有这些仅适用于ES pre-2.0,因为starting in 2.0,and
/ 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