能否用bodybuilder构建含bucket_selector的ELS聚合查询?
使用bodybuilder构建包含bucket_selector的Elasticsearch聚合查询
当然可以用bodybuilder来实现你想要的这种聚合结构!bucket_selector作为管道聚合,完全能通过bodybuilder的嵌套聚合能力来构建,下面我直接给你对应需求的实现示例:
具体代码实现
假设你用的是JavaScript版本的bodybuilder,代码可以这么写:
const bodybuilder = require('bodybuilder'); // 构建聚合查询 const queryBody = bodybuilder() // 顶级terms聚合:aggname1 .agg('terms', 'field1', 'aggname1', { size: 5 }) // 在aggname1内部添加avg聚合:aggname2 .agg('avg', 'field2', 'aggname2', {}, 'aggname1') // 在aggname1内部添加bucket_selector管道聚合:a_bucker_filter .agg('bucket_selector', null, 'a_bucker_filter', { buckets_path: { bucker_selector_name: 'aggname2' }, script: 'params.bucker_selector_name > 10' // 替换成你的实际脚本逻辑 }, 'aggname1') .build(); console.log(JSON.stringify(queryBody, null, 2));
生成的聚合结构说明
运行上面的代码后,生成的aggs部分会和你期望的结构完全一致:
"aggs": { "aggname1": { "terms": { "field": "field1", "size": 5 }, "aggs": { "aggname2": { "avg": { "field": "field2" } }, "a_bucker_filter": { "bucket_selector": { "buckets_path": { "bucker_selector_name": "aggname2" }, "script": "params.bucker_selector_name > 10" } } } } }
这里需要注意几个关键点:
- 嵌套聚合时,最后一个参数要指定父聚合的名称(比如
'aggname1'),这样bodybuilder才会把后续的聚合放到对应父聚合的aggs下 bucket_selector的script部分需要替换成你实际的过滤逻辑,比如判断平均值大于某个阈值、满足特定条件等- 如果你的脚本比较复杂,也可以用
inline、file或者id的方式来定义,bodybuilder同样支持这种格式
内容的提问来源于stack exchange,提问作者Alejandro
相关产品推荐
相关产品推荐

