快速弹性搜索案例,那么等同于什么?

时间:2016-08-18 09:06:08

标签: elasticsearch

我需要在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中是否有任何语言支持这种独家包装?或者任何其他更快的方法会产生相同的结果?

谢谢!

1 个答案:

答案 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;是您在过滤器中使用的字段。