gpt4 book ai didi

elasticsearch - 如何在 ElasticSearch 中展平深度聚合?

转载 作者:行者123 更新时间:2023-12-04 15:00:57 25 4
gpt4 key购买 nike

我在索引中的文档如下所示:

{
"foo": null,
"bars": [
{
"baz": "BAZ",
"qux": null,
"bears": [
{
"fruit": "banana"
}
]
}
]
}
我想聚合 .bars[].bears[].fruit 的唯一值对每个找到的值进行计数。但是,我也只想计算符合 foo 上某些条件的文档的这些深度值。 ,以及 bars[] 的值匹配 baz 上的某些条件和 qux .我还想聚合所有文档,忽略搜索查询的任何内容。
以下查询完成了我想做的一切:
{
"aggs": {
"global": {
"global": {},
"aggs": {
"notFoo": {
"filter": {
"bool": {
"must_not": [
{
"exists": {
"field": "foo"
}
}
]
}
},
"aggs": {
"bars": {
"nested": {
"path": "bars"
},
"aggs": {
"notValueN": {
"filter": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"terms": {
"bars.baz": [
"value1",
"value2",
"value3"
]
}
},
{
"terms": {
"bars.qux": [
"value4",
"value5",
"value6"
]
}
}
],
"minimum_should_match": 1
}
}
]
}
},
"aggs": {
"bears": {
"nested": {
"path": "bars.bears"
},
"aggs": {
"rules": {
"terms": {
"field": "bars.bears.fruit"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
这个查询有效,但感觉相当大和繁重。为了得到我在响应中寻找的结果,我必须访问 .aggregations.global.bars.notValueN.bears.fruit.buckets .有没有办法展平这个大查询?就目前而言,如果稍后需要引入任何其他条件,则此查询很难维护。

最佳答案

ES唯一支持的地方object key flattening位于集群设置 API 中。不幸的是,这个策略不能 用于 API 的其他部分,包括聚合。
不过,还有一些其他技巧值得一提。
1. 首先,有聚合元数据。
任何负责对重度嵌套聚合结果进行后处理的人都会很高兴知道目标存储桶路径。您可以通过 aggregation metadata 提供它条款:

POST your-index/_search
{
"aggs": {
"global": {
"global": {},
"meta": {
"accessor_path": "aggs.global.Foo...." <---
},
...
这将返回
{
"aggregations" : {
"global" : {
"meta" : {
"accessor_path" : "aggs.global.Foo..." <---
},
"Foo" : {
2. 然后是响应过滤
如果在同一个请求正文中包含多个(子)聚合,则可以通过 filter_path URI parameter 减少响应的“体积”。 :
POST your-index/_search/template?filter_path=aggregations.global.meta,aggregations.global.*.*.*.*.*.buckets
{
"aggs": {
"global": {
...
这可能会也可能不会真正帮助您,因为您的 agg 查询看起来很简单并且没有太多子条款。
3. 最后说一下可维护性
在处理可重用查询时,Elasticsearch 提供了 Search template API .您将构建一个包含参数化 mustache 的脚本。模板,然后在查询时提供参数。
在您的特定用例中,我建议如下:
  • 存储 mustache 模板脚本:

  • POST _scripts/nested_bars_query
    {
    "script": {
    "lang": "mustache",
    "source": """
    {
    "query": {{#toJson}}raw_search_query{{/toJson}},
    "aggs": {
    "global": {
    "global": {},
    "meta": {
    "accessor_path": "{{accessor_path}}"
    },
    "aggs": {
    "{{notXYZ.agg_name}}": {
    "filter": {
    "bool": {
    "must_not": [
    {
    "exists": {
    "field": "{{notXYZ.field_name}}"
    }
    }
    ]
    }
    },
    "aggs": {
    "bars": {
    "nested": {
    "path": "bars"
    },
    "aggs": {
    "{{notValueN.agg_name}}": {
    "filter": {
    "bool": {
    "filter": [
    {
    "bool": {
    "should": {{#toJson}}notValueN.raw_should_clauses{{/toJson}},
    "minimum_should_match": 1
    }
    }
    ]
    }
    },
    "aggs": {
    "bears": {
    "nested": {
    "path": "bars.bears"
    },
    "aggs": {
    "rules": {
    "terms": {
    "field": "bars.bears.fruit"
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    """
    }
    }
  • 瞄准 /_search/template/具有搜索模板 ID ( nested_bars_query ) 的端点。另外,指定 filter_path和元数据 accessor_path上面讨论过的:

  • POST your-index-name/_search/template?filter_path=aggregations.global.meta,aggregations.global.*.*.*.*.*.buckets
    {
    "id": "nested_bars_query",
    "params": {
    "raw_search_query": {
    "match_all": {}
    },
    "accessor_path": "aggs.global.Foo.bars.notValueN.bears.rules.buckets",
    "notXYZ": {
    "agg_name": "Foo",
    "field_name": "foo"
    },
    "notValueN": {
    "agg_name": "notValueN",
    "raw_should_clauses": [
    {
    "terms": {
    "bars.baz": [
    "BAZ",
    "value2",
    "value3"
    ]
    }
    },
    {
    "terms": {
    "bars.qux": [
    "value4",
    "value5",
    "value6"
    ]
    }
    }
    ]
    }
    }
    }
    您当然可以通过消除定义自定义 agg_name 的可能性来标准化上述内容。等
    如果以后需要引入附加条件,可以修改 raw_should_clauses params 里面的列表.

    关于elasticsearch - 如何在 ElasticSearch 中展平深度聚合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66955965/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com