我需要在Elasticsearch中构建一个独占的分组聚合(即,文档被分配到FIRST桶以满足标准,而不是满足它的所有桶,因为过滤器可能重叠 - 这与CASE WHEN的行为相同那么在SQL环境中也是如此)。目前我正在使用Filters Aggregation加上Bool Query/Filter来实现我想要的效果。我们的想法是使用" must"并且" must_not" " Bool Query"的部分内容"必须"是我的过滤器和" must_not"是以前已经使用过的所有其他过滤器的集合。一个例子是:
GET _search
{
"query":{"match_all":{}},
"size":0,
"aggs":{
"bin_1": {
"filter": {
"bool": {
"must": { <filter1> },
"must_not": { <empty> }
}
}
},
"bin_2": {
"filter": {
"bool": {
"must": { <filter2> },
"must_not": { <filter1> }
}
}
},
"bin_3": {
"filter": {
"bool": {
"must": { <filter3> },
"must_not": { <filter1>, <filter2> }
}
}
},
"bin_else": {
"filter": {
"bool": {
"must": { <empty> },
"must_not": { <filter1>, <filter2>, <filter3> }
}
}
}
}
}
在关系方法中,CASE WHEN子句可以实现同样的目的:
CASE WHEN <filter1> THEN <bin_1>
WHEN <filter2> THEN <bin_2>
WHEN <filter3> THEN <bin_3>
ELSE <bin_else>
END
这种方法的问题是,我添加的桶越多越慢(在我的实际情况下,我甚至有嵌套桶)。在Elastic中是否有任何语言支持这种独家包装?或者任何其他更快的方法会产生相同的结果?
谢谢!
答案 0 :(得分:2)
我认为解决方案是脚本字段。它将使用if else逻辑,因此不会使用额外的条件。我只是不知道你正在使用什么样的过滤器,但应该可以实现我想的任何东西。我会在这里写一个等价的
SELECT
CASE WHEN <filter1> THEN <bin_1>
WHEN <filter2> THEN <bin_2>
ELSE <bin_else>
END as binning
FROM SOMETHING
使用无痛语言的脚本字段实现。如下所述:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html 这里没有痛苦: https://www.elastic.co/guide/en/elasticsearch/painless/5.6/painless-examples.html
GET _search
{
"query" : { "match_all": {} },
"script fields" : {
"binning" : {
"script" : {
"lang": "painless",
"source": "if (<filter>) {return <bin1>;} else if (<filter2>) {return <bin2>;} else {return <bin3>;}"
}
}
}
&#34;过滤器&#34;将是这样的:doc [&#39; my_field&#39;]。value ==&#34; value1&#34;在哪里&#39; my_field&#39;是您在过滤器中使用的字段。