最近在使用elasticsearch进行聚合时遇到一个问题,有一个字段是数组类型,该字段存储的是客户订阅的产品id,要聚合统计每个客户订阅了几个产品,比如统计订阅了2到3个的。
这个时候就要知道每个客户该字段数组的长度,但是elasticsearch聚合文档里没有相关操作,查阅资料后发现要用script来处理。
DSL语句如下:
GET customer/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"customer_id": {
"value": "110600001170"
}
}
}
]
}
},
"size": 0,
"aggs": {
"count1": {
"sum": {
"script": {
"source": "doc['now_subscribe_value_added_products'].length"
}
}
}
}
}
通过”source”: “doc[‘xxx’].length”来获取数组长度。
如果要聚合订阅产品数4到6之间可以这样写:
GET customer/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"customer_id": {
"value": "110600001170"
}
}
}
]
}
},
"size": 0,
"aggs": {
"count1": {
"sum": {
"script": {
"source": "doc['now_subscribe_value_added_products'].length>3&&doc['now_subscribe_value_added_products'].length<7"
}
}
}
}
}
java代码实例如下:
//订阅产品数小于等于1
Script script1 = new Script("doc['now_subscribe_value_added_products'].length<2");
//订阅产品数2-3
Script script2 = new Script("doc['now_subscribe_value_added_products'].length>1&&doc['now_subscribe_value_added_products'].length<4");
//订阅产品数4-6
Script script3 = new Script("doc['now_subscribe_value_added_products'].length>3&&doc['now_subscribe_value_added_products'].length<7");
//订阅产品数7-10
Script script4 = new Script("doc['now_subscribe_value_added_products'].length>6&&doc['now_subscribe_value_added_products'].length<11");
//订阅产品数大于等于11
Script script5 = new Script("doc['now_subscribe_value_added_products'].length>10");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("data_type", 1))
.filter(wrapperQueryBuilder);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder)
.aggregation(AggregationBuilders.sum("count1").script(script1)
.aggregation(AggregationBuilders.sum("count2").script(script2)
.aggregation(AggregationBuilders.sum("count3").script(script3)
.aggregation(AggregationBuilders.sum("count4").script(script4)
.aggregation(AggregationBuilders.sum("count5").script(script5);
searchSourceBuilder.size(0)
searchRequest.source(searchSourceBuilder);
SearchResponse result = restHighLevelClient.search(searchRequest);
Aggregations aggregations = result.getAggregations();
String count1 = String.valueOf(((ParsedSum) aggregations.get("count1")).getValue());
String count2 = String.valueOf(((ParsedSum) aggregations.get("count2")).getValue());
String count3 = String.valueOf(((ParsedSum) aggregations.get("count3")).getValue());
String count4 = String.valueOf(((ParsedSum) aggregations.get("count4")).getValue());
String count5 = String.valueOf(((ParsedSum) aggregations.get("count5")).getValue());
网上看其他文章是用的size()来获取,可能是es版本问题,我测试的时候有问题。
"script": {
"source": "params._source.xxx.size()"
}
关于elasticsearch使用script聚合你还可以看下以下文章:
Elasticsearch计算Array中元素的个数
How to get array count of nested object in elastic-search
elasticsearch中多个字段聚合及java实现
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80372.html