Elasticsearch实战——聚合分析

Elasticsearch实战——聚合分析

1. 指标聚合

1.1 max agg(求最大值)

max agg用于统计最大值:统计价格最高的值

GET website/_search
{
    
    
	"size":"0",
	"aggs":{
    
    
		"max_price":{
    
    
			"max":{
    
    
				"field":"price"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
MaxAggregationBuilder max_price = AggregationBuilders.max("max_price");
max_price.field("price");
builder.aggregation(max_price);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedMax max = search.getAggregations().get("max_price");
double value = max.getValue();
System.out.println(value);

1.2 min agg(求最小值)

min agg用于统计最小值:统计价格最小的值

{
    
    
	"size":"0",
	"aggs":{
    
    
		"min_price":{
    
    
			"min":{
    
    
				"field":"price"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
MinAggregationBuilder min_price = AggregationBuilders.min("min_price");
min_price.field("price");
builder.aggregation(min_price);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedMin min = search.getAggregations().get("min_price");
double value = min.getValue();
System.out.println(value);

1.3 avg agg(求平均值)

avg agg用于计算平均值,例如:求价格的平均值。

{
    
    
	"size":"0",
	"aggs":{
    
    
		"avg_price":{
    
    
			"avg":{
    
    
				"field":"price"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
AvgAggregationBuilder avg_price = AggregationBuilders.avg("avg_price");
avg_price.field("price");
builder.aggregation(avg_price);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedAvg avg = search.getAggregations().get("avg_price");
double value = avg.getValue();
System.out.println(value);

1.4 sum agg(求总和)

sum agg用于求总和,例如:求价格的总计。

{
    
    
	"size":"0",
	"aggs":{
    
    
		"sum_price":{
    
    
			"sum":{
    
    
				"field":"price"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
SumAggregationBuilder sum_price = AggregationBuilders.sum("sum_price");
sum_price.field("price");
builder.aggregation(sum_price);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedSum sum = search.getAggregations().get("sum_price");
double value = sum.getValue();
System.out.println(value);

1.5 cardinality agg(去重统计)

cardinality agg用于去重统计,相当于sql语句中的distinct操作,例如,统计北京市下面有多少个区。

{
    
    
	"query":{
    
    
		"term":{
    
    
			"city":"北京市"
		}	
	},
	"size":"0",
	"aggs":{
    
    
		"districtCount":{
    
    
			"cardinality":{
    
    
				"field":"district"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("city","北京市"));
CardinalityAggregationBuilder districtCount = AggregationBuilders.cardinality("districtCount");
districtCount.field("district");
builder.aggregation(districtCount);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedCardinality cardinality = search.getAggregations().get("districtCount");
double value = cardinality.value();
System.out.println(value);

1.6 stats agg(同时统计 count、max、min、avg和sum这5个指标)

例如统计北京市下的price的count、max、min、avg和sum这5个指标

{
    
    
	"query":{
    
    
		"term":{
    
    
			"city":"北京市"
		}	
	},
	"size":"0",
	"aggs":{
    
    
		"stats_count":{
    
    
			"stats":{
    
    
				"field":"price"
			}
		}
	}
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("city","北京市"));
StatsAggregationBuilder stats_count = AggregationBuilders.stats("stats_count");
stats_count.field("price");
builder.aggregation(stats_count);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedStats stats = search.getAggregations().get("stats_count");
long count = stats.getCount();
double max = stats.getMax();
double min = stats.getMin();
double avg = stats.getAvg();
double sum = stats.getSum();
System.out.println(count);
System.out.println(max);
System.out.println(min);
System.out.println(avg);
System.out.println(sum);

1.7 extended stats agg(高级统计)

extended_stats agg用于高级统计,和基本统计功能类型,但是会比基本统计多2个统计结果:平方差、方差、标准差、平均值加/减两个标准差的区间。

{
    
    
	"query":{
    
    
		"term":{
    
    
			"city":"北京市"
		}	
	},
	"size":"0",
	"aggs":{
    
    
		"extended_stats_count":{
    
    
			"extended_stats":{
    
    
				"field":"price"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "extended_stats_count": {
    
    
      "count": 1000,
      "min": 1.03,
      "max": 1000.86,
      "avg": 488.18921,
      "sum": 488189.21,
      "sum_of_squares": 322466013.0603,
      "variance": 84137.30829987586,
      "std_deviation": 290.0643175226416,
      "std_deviation_bounds": {
    
    
        "upper": 1068.3178450452833,
        "lower": -91.9394250452832
      }
    }
  }
}

1.8 percentiles agg(百分位统计)

百分位数是一个统计学术语,如果将一组数据从大到小排序,并计算相应的累计百分位,某一百分位所对应的数据的值就称这一百分位的百分位数。

{
    
    
	"query":{
    
    
		"term":{
    
    
			"city":"北京市"
		}	
	},
	"size":"0",
	"aggs":{
    
    
		"percentiles_count":{
    
    
			"percentiles":{
    
    
				"field":"price"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "percentiles_count": {
    
    
      "values": {
    
    
        "1.0": 10.325,
        "5.0": 51.269999999999996,
        "25.0": 238.5222222222222,
        "50.0": 460.7083333333333,
        "75.0": 750.3386666666668,
        "95.0": 947.97,
        "99.0": 989.98
      }
    }
  }
}

1.9 value count agg(统计文档中包含某个字段的文档数量)

例如统计文档中包含city字段的文档数量:

{
    
    
	"size":"0",
	"aggs":{
    
    
		"doc_count":{
    
    
			"value_count":{
    
    
				"field":"city"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "doc_count": {
    
    
      "value": 1000
    }
  }
}

2. 桶聚合

Bucket可以理解为一个桶,它会遍历文档中的内容,凡是符合某一要求的就放入一个桶中,分桶相当于sql中的group by。

2.1 terms agg(分组聚合)

统计烟酒专卖这个分类下在每个区的分布:

{
    
    
	"size":"0",
	"query":{
    
    
		"term":{
    
    
			"category":"烟酒专卖"
		}
	},
	"aggs":{
    
    
		"district_count":{
    
    
			"terms":{
    
    
				"field":"district"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "district_count": {
    
    
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
    
    
          "key": "丰台区",
          "doc_count": 58
        },
        {
    
    
          "key": "大兴区",
          "doc_count": 52
        },
        {
    
    
          "key": "房山区",
          "doc_count": 11
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("category","烟酒专卖"));
TermsAggregationBuilder district_count = AggregationBuilders.terms("district_count");
district_count.field("district");
builder.aggregation(district_count);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedTerms terms = search.getAggregations().get("district_count");
String name = terms.getName();
System.out.println(name);
for (Terms.Bucket bucket : terms.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

还可以进行下钻聚合:统计烟酒专卖这个分类下在每个省、市、区的分布:

{
    
    
  "size": 0,
  "query": {
    
    
    "term": {
    
    
      "category": "烟酒专卖"
    }
  },
  "aggs": {
    
    
    "province_count": {
    
    
      "terms": {
    
    
        "field": "province"
      },
      "aggs": {
    
    
        "city_count": {
    
    
          "terms": {
    
    
            "field": "city"
          },
          "aggs": {
    
    
            "district_count": {
    
    
              "terms": {
    
    
                "field": "district"
              }
            }
          }
        }
      }
    }
  }
}
{
    
    
  "aggregations": {
    
    
    "province_count": {
    
    
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
    
    
          "key": "北京市",
          "doc_count": 121,
          "city_count": {
    
    
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
    
    
                "key": "北京市",
                "doc_count": 121,
                "district_count": {
    
    
                  "doc_count_error_upper_bound": 0,
                  "sum_other_doc_count": 0,
                  "buckets": [
                    {
    
    
                      "key": "丰台区",
                      "doc_count": 58
                    },
                    {
    
    
                      "key": "大兴区",
                      "doc_count": 52
                    },
                    {
    
    
                      "key": "房山区",
                      "doc_count": 11
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("category","烟酒专卖"));
TermsAggregationBuilder province_count = AggregationBuilders.terms("province_count");
province_count.field("province");
TermsAggregationBuilder city_count = AggregationBuilders.terms("city_count");
city_count.field("city");
TermsAggregationBuilder district_count = AggregationBuilders.terms("district_count");
district_count.field("district");
city_count.subAggregation(district_count);
province_count.subAggregation(city_count);
builder.aggregation(province_count);
builder.size(0);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedTerms provinceTerms = search.getAggregations().get("province_count");
String province_count_name = provinceTerms.getName();
System.out.println(province_count_name);
for (Terms.Bucket provinceBucket : provinceTerms.getBuckets()) {
    
    
    String province = provinceBucket.getKeyAsString();
    long provinceCount = provinceBucket.getDocCount();
    System.out.println(province+"="+provinceCount);
    ParsedTerms cityTerms = provinceBucket.getAggregations().get("city_count");
    String city_count_name = cityTerms.getName();
    System.out.println(city_count_name);
    for (Terms.Bucket cityBucket : cityTerms.getBuckets()) {
    
    
        String city = cityBucket.getKeyAsString();
        long cityCount = cityBucket.getDocCount();
        System.out.println(city+"="+cityCount);
        ParsedTerms districtTerms = cityBucket.getAggregations().get("district_count");
        String district_count_name = districtTerms.getName();
        System.out.println(district_count_name);
        for (Terms.Bucket districtBucket : districtTerms.getBuckets()) {
    
    
            String district = districtBucket.getKeyAsString();
            long districtCount = districtBucket.getDocCount();
            System.out.println(district+"="+districtCount);
        }
    }
}

2.2 filter agg(过滤聚合)

把符合过滤器中的条件的文档分到一个桶中。

统计北京城市下面的总数量和平均价格:

{
    
    
	"size":0,
	"aggs":{
    
    
		"city_avg_price":{
    
    
			"filter":{
    
    
				"term":{
    
    
					"city":"北京市"
				}
			},
			"aggs":{
    
    
				"avg_price":{
    
    
					"avg":{
    
    
						"field":"price"
					}
				}
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "city_avg_price": {
    
    
      "doc_count": 1000,
      "avg_price": {
    
    
        "value": 488.18921
      }
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
FilterAggregationBuilder filter = AggregationBuilders.filter("city_avg_price", QueryBuilders.termQuery("city", "北京市"));
AvgAggregationBuilder avg_price = AggregationBuilders.avg("avg_price");
avg_price.field("price");
filter.subAggregation(avg_price);
builder.aggregation(filter);
SearchResponse search = server.search(builder, index);
ParsedFilter city_avg_price = search.getAggregations().get("city_avg_price");
long count = city_avg_price.getDocCount();

String filterName = city_avg_price.getName();
ParsedAvg avg = city_avg_price.getAggregations().get("avg_price");
double value = avg.getValue();
System.out.println(filterName+"="+count+";avg="+value);

2.3 filters agg(多过滤器聚合)

把符合多个过滤条件的文档分到不同的桶中。

{
    
    
  "size": 0,
  "aggregations": {
    
    
    "district_avg_price": {
    
    
      "filters": {
    
    
        "filters": {
    
    
          "filter1": {
    
    
            "term": {
    
    
              "district": {
    
    
                "value": "朝阳区",
                "boost": 1
              }
            }
          },
          "filter2": {
    
    
            "term": {
    
    
              "district": {
    
    
                "value": "丰台区",
                "boost": 1
              }
            }
          }
        },
        "other_bucket": false,
        "other_bucket_key": "_other_"
      },
      "aggregations": {
    
    
        "avg_price": {
    
    
          "avg": {
    
    
            "field": "price"
          }
        }
      }
    }
  }
}
{
    
    
  "aggregations": {
    
    
    "district_avg_price": {
    
    
      "buckets": {
    
    
        "filter1": {
    
    
          "doc_count": 98,
          "avg_price": {
    
    
            "value": 490.5181632653061
          }
        },
        "filter2": {
    
    
          "doc_count": 102,
          "avg_price": {
    
    
            "value": 520.1826470588235
          }
        }
      }
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
FiltersAggregator.KeyedFilter[] filters = {
    
    
    new FiltersAggregator.KeyedFilter("filter1",QueryBuilders.termQuery("district","朝阳区")),
    new FiltersAggregator.KeyedFilter("filter2",QueryBuilders.termQuery("district","丰台区"))
};
FiltersAggregationBuilder filter = AggregationBuilders.filters("district_avg_price", filters);
AvgAggregationBuilder avg_price = AggregationBuilders.avg("avg_price");
avg_price.field("price");
filter.subAggregation(avg_price);
builder.aggregation(filter);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedFilters district_avg_price = search.getAggregations().get("district_avg_price");
for (Filters.Bucket bucket : district_avg_price.getBuckets()) {
    
    
    long count = bucket.getDocCount();
    String key = bucket.getKeyAsString();
    ParsedAvg avg = bucket.getAggregations().get("avg_price");
    double value = avg.value();
    System.out.println(key+"="+count+";avg="+value);
}

2.4 range agg(范围聚合)

{
    
    
  "size": 0,
  "aggs":{
    
    
  	"price_ranges":{
    
    
  		"range":{
    
    
  			"field":"price",
  			"ranges":[
  				{
    
    
  					"from":0,
  					"to":200
  				},
  				{
    
    
  					"from":201,
  					"to":500
  				},
  				{
    
    
  					"from":501
  				}
  			]
  		}
  	}
  }
}
{
    
    
  "aggregations": {
    
    
    "price_ranges": {
    
    
      "buckets": [
        {
    
    
          "key": "0.0-200.0",
          "from": 0,
          "to": 200,
          "doc_count": 204
        },
        {
    
    
          "key": "201.0-500.0",
          "from": 201,
          "to": 500,
          "doc_count": 327
        },
        {
    
    
          "key": "501.0-*",
          "from": 501,
          "doc_count": 465
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
RangeAggregationBuilder price_ranges = AggregationBuilders.range("price_ranges");
price_ranges.field("price");
price_ranges.addRange(0,200);
price_ranges.addRange(201,500);
price_ranges.addUnboundedFrom(501);
builder.aggregation(price_ranges);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedRange price_ranges_agg = search.getAggregations().get("price_ranges");
for (Range.Bucket bucket : price_ranges_agg.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

range agg不仅可以对数值类型字段进行范围统计,可以作用在日期类型上。

{
    
    
  "size": 0,
  "aggs": {
    
    
    "date_ranges": {
    
    
      "range": {
    
    
        "field": "publishAt",
        "format":"yyyy-MM-dd",
        "ranges": [
          {
    
    
            "to": "2009-12-31"
          },
          {
    
    
            "from": "2010-01-01",
            "to": "2015-12-31"
          },
          {
    
    
            "from": "2016-01-01"
          }
        ]
      }
    }
  }
}
{
    
    
  "aggregations": {
    
    
    "date_ranges": {
    
    
      "buckets": [
        {
    
    
          "key": "*-2009-12-31",
          "to": 1262217600000,
          "to_as_string": "2009-12-31",
          "doc_count": 436
        },
        {
    
    
          "key": "2010-01-01-2015-12-31",
          "from": 1262304000000,
          "from_as_string": "2010-01-01",
          "to": 1451520000000,
          "to_as_string": "2015-12-31",
          "doc_count": 332
        },
        {
    
    
          "key": "2016-01-01-*",
          "from": 1451606400000,
          "from_as_string": "2016-01-01",
          "doc_count": 232
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
RangeAggregationBuilder date_ranges = AggregationBuilders.range("date_ranges");
date_ranges.field("publishAt");
date_ranges.format("yyy-MM-dd");
date_ranges.addUnboundedTo(1262217600000d);
date_ranges.addRange(1262304000000d,1451520000000d);
date_ranges.addUnboundedFrom(1451606400000d);
builder.aggregation(date_ranges);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedRange date_ranges_agg = search.getAggregations().get("date_ranges");
for (Range.Bucket bucket : date_ranges_agg.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

2.5 date range agg(日期访问聚合)

date range agg专门用于日期类型的范围聚合,和range agg的区别在于日期的起止时间可以使用数学表达式。例如:统计2010-01-01之前2010-01-01到2015-01-012015-01-01到现在的数据

{
    
    
	"size":0,
	"aggs":{
    
    
		"publish_range":{
    
    
			"date_range":{
    
    
				"field":"publishAt",
				"format":"yyyy-MM-dd",
				"ranges":[
					{
    
    
						"to":"now-120M/M"
					},
					{
    
    
						"from":"now-120M/M",
						"to":"now-60M/M"
					},
					{
    
    
						"from":"now-60M/M"
					}
				]
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "publish_range": {
    
    
      "buckets": [
        {
    
    
          "key": "*-2010-01-01",
          "to": 1262304000000,
          "to_as_string": "2010-01-01",
          "doc_count": 436
        },
        {
    
    
          "key": "2010-01-01-2015-01-01",
          "from": 1262304000000,
          "from_as_string": "2010-01-01",
          "to": 1420070400000,
          "to_as_string": "2015-01-01",
          "doc_count": 276
        },
        {
    
    
          "key": "2015-01-01-*",
          "from": 1420070400000,
          "from_as_string": "2015-01-01",
          "doc_count": 288
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
DateRangeAggregationBuilder date_ranges = AggregationBuilders.dateRange("date_ranges");
date_ranges.field("publishAt");
date_ranges.format("yyy-MM-dd");
date_ranges.addUnboundedTo("now-120M/M");
date_ranges.addRange("now-120M/M","now-60M/M");
date_ranges.addUnboundedFrom("now-60M/M");
builder.aggregation(date_ranges);
SearchResponse search = server.search(builder, index);
ParsedDateRange date_ranges_agg = search.getAggregations().get("date_ranges");
for (Range.Bucket bucket : date_ranges_agg.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
	long count = bucket.getDocCount();
	System.out.println(key+"="+count);
}

2.6 histogram agg(数值类型直方图聚合)

{
    
    
	"size":0,
	"aggs":{
    
    
		"price_histogram":{
    
    
			"histogram":{
    
    
				"field":"price",
				"interval":200
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "price_histogram": {
    
    
      "buckets": [
        {
    
    
          "key": 0,
          "doc_count": 204
        },
        {
    
    
          "key": 200,
          "doc_count": 225
        },
        {
    
    
          "key": 400,
          "doc_count": 180
        },
        {
    
    
          "key": 600,
          "doc_count": 197
        },
        {
    
    
          "key": 800,
          "doc_count": 192
        },
        {
    
    
          "key": 1000,
          "doc_count": 2
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
HistogramAggregationBuilder price_distogram = AggregationBuilders.histogram("price_histogram");
price_distogram.interval(200);
price_distogram.field("price");
builder.aggregation(price_distogram);
SearchResponse search = server.search(builder, index);
ParsedHistogram histogram = search.getAggregations().get("price_histogram");
for (Histogram.Bucket bucket : histogram.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

2.7 date histogram agg(时间直方图聚合)

用于统计每个月/年/季度。

可选参数:

  • calendar_interval

    日历感知使用calendar_interval参数进行配置。日历间隔只能以单位(1d或1M)的数量指定。不支持2d之类的倍数,并且会引发异常。

    日历间隔的可接受的单位有:

    1m(一分钟),1h(一小时),1d(一天),1w(一个星期),1M(一个月),1q(一个季度),1y(一年)

  • fixed_interval

    固定间隔使用fixed_interval参数配置。

    与日历感知间隔相比,固定间隔是固定数量的国际时间单位,并且永远不会偏离,无论她们落在日历的什么位置。一秒始终由1000毫秒组成。

    这意味着,固定间隔不能表示其他单位,例如月份,因为一个月的持续时间不是固定数量。指定月份、季度或年将会引发异常。

    固定间隔可以接受的单位有:

    1s,1m,1h,1d

统计每年的数量:

{
    
    
	"size":0,
	"aggs":{
    
    
		"publish_range":{
    
    
			"date_histogram":{
    
    
				"field":"publishAt",
				"format":"yyyy-MM-dd",
				"calendar_interval":"1y"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "publish_range": {
    
    
      "buckets": [
        {
    
    
          "key_as_string": "2001-01-01",
          "key": 978307200000,
          "doc_count": 53
        },
        {
    
    
          "key_as_string": "2002-01-01",
          "key": 1009843200000,
          "doc_count": 40
        },
        {
    
    
          "key_as_string": "2003-01-01",
          "key": 1041379200000,
          "doc_count": 39
        },
        {
    
    
          "key_as_string": "2004-01-01",
          "key": 1072915200000,
          "doc_count": 44
        },
        {
    
    
          "key_as_string": "2005-01-01",
          "key": 1104537600000,
          "doc_count": 53
        },
        {
    
    
          "key_as_string": "2006-01-01",
          "key": 1136073600000,
          "doc_count": 58
        },
        {
    
    
          "key_as_string": "2007-01-01",
          "key": 1167609600000,
          "doc_count": 54
        },
        {
    
    
          "key_as_string": "2008-01-01",
          "key": 1199145600000,
          "doc_count": 51
        },
        {
    
    
          "key_as_string": "2009-01-01",
          "key": 1230768000000,
          "doc_count": 44
        },
        {
    
    
          "key_as_string": "2010-01-01",
          "key": 1262304000000,
          "doc_count": 63
        },
        {
    
    
          "key_as_string": "2011-01-01",
          "key": 1293840000000,
          "doc_count": 48
        },
        {
    
    
          "key_as_string": "2012-01-01",
          "key": 1325376000000,
          "doc_count": 60
        },
        {
    
    
          "key_as_string": "2013-01-01",
          "key": 1356998400000,
          "doc_count": 60
        },
        {
    
    
          "key_as_string": "2014-01-01",
          "key": 1388534400000,
          "doc_count": 45
        },
        {
    
    
          "key_as_string": "2015-01-01",
          "key": 1420070400000,
          "doc_count": 56
        },
        {
    
    
          "key_as_string": "2016-01-01",
          "key": 1451606400000,
          "doc_count": 53
        },
        {
    
    
          "key_as_string": "2017-01-01",
          "key": 1483228800000,
          "doc_count": 55
        },
        {
    
    
          "key_as_string": "2018-01-01",
          "key": 1514764800000,
          "doc_count": 64
        },
        {
    
    
          "key_as_string": "2019-01-01",
          "key": 1546300800000,
          "doc_count": 58
        },
        {
    
    
          "key_as_string": "2020-01-01",
          "key": 1577836800000,
          "doc_count": 2
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
DateHistogramAggregationBuilder publish_histogram = AggregationBuilders.dateHistogram("publish_histogram");
publish_histogram.field("publishAt");
publish_histogram.format("yyyy-MM-dd");
publish_histogram.calendarInterval(DateHistogramInterval.YEAR);
builder.aggregation(publish_histogram);
System.out.println(builder.toString());
SearchResponse search = server.search(builder, index);
ParsedDateHistogram dateHistogram = search.getAggregations().get("publish_histogram");
for (Histogram.Bucket bucket : dateHistogram.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

2.8 missing agg(空值聚合)

把文档中所有缺失该字段的文档分到一个桶中。

{
    
    
	"size":0,
	"aggs":{
    
    
		"with_out_price":{
    
    
			"missing":{
    
    
				"field":"price"
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "with_out_price": {
    
    
      "doc_count": 0
    }
  }
}

2.9 geo distance agg(对地理点(geo_point)做范围统计)

距离天安门的距离范围统计。

{
    
    
	"size":0,
	"aggs":{
    
    
		"tiananmeng":{
    
    
			"geo_distance":{
    
    
				"field":"location",
				"origin":"39.908676,116.397217",
				"unit":"km",
				"ranges":[
					{
    
    
						"to":10
					},
					{
    
    
						"from":10,
						"to":20
					},
					{
    
    
						"from":20,
						"to":50
					},
					{
    
    
						"from":50
					}
				]
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "tiananmeng": {
    
    
      "buckets": [
        {
    
    
          "key": "*-10.0",
          "from": 0,
          "to": 10,
          "doc_count": 61
        },
        {
    
    
          "key": "10.0-20.0",
          "from": 10,
          "to": 20,
          "doc_count": 285
        },
        {
    
    
          "key": "20.0-50.0",
          "from": 20,
          "to": 50,
          "doc_count": 499
        },
        {
    
    
          "key": "50.0-*",
          "from": 50,
          "doc_count": 155
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
GeoPoint point = new GeoPoint();
point.resetLat(39.908676);
point.resetLon(116.397217);
GeoDistanceAggregationBuilder tiananmeng = AggregationBuilders.geoDistance("tiananmeng", point);
tiananmeng.field("location");
tiananmeng.unit(DistanceUnit.KILOMETERS);
tiananmeng.addUnboundedTo(10);
tiananmeng.addRange(10,20);
tiananmeng.addRange(20,50);
tiananmeng.addUnboundedFrom(50);
builder.aggregation(tiananmeng);
SearchResponse search = server.search(builder, index);
ParsedGeoDistance geoDistance = search.getAggregations().get("tiananmeng");
for (Range.Bucket bucket : geoDistance.getBuckets()) {
    
    
    long count = bucket.getDocCount();
    String key = bucket.getKeyAsString();
    System.out.println(key+"="+count);
}

2.10 ip range agg(IP类型的数据范围聚合)

{
    
    
	"size":0,
	"aggs":{
    
    
		"ip_ranges":{
    
    
			"ip_range":{
    
    
				"field":"ip",
				"ranges":[
					{
    
    
						"to":"106.86.20.132"
					},
					{
    
    
						"from":"106.86.20.132",
						"to":"107.86.20.132"
					},
					{
    
    
						"from":"107.86.20.132"
					}
				]
			}
		}
	}
}
{
    
    
  "aggregations": {
    
    
    "ip_ranges": {
    
    
      "buckets": [
        {
    
    
          "key": "*-106.86.20.132",
          "to": "106.86.20.132",
          "doc_count": 261
        },
        {
    
    
          "key": "106.86.20.132-107.86.20.132",
          "from": "106.86.20.132",
          "to": "107.86.20.132",
          "doc_count": 74
        },
        {
    
    
          "key": "107.86.20.132-*",
          "from": "107.86.20.132",
          "doc_count": 665
        }
      ]
    }
  }
}
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(0);
IpRangeAggregationBuilder ip_ranges = AggregationBuilders.ipRange("ip_ranges");
ip_ranges.field("ip");
ip_ranges.addUnboundedTo("106.86.20.132");
ip_ranges.addRange("106.86.20.132","107.86.20.132");
ip_ranges.addUnboundedFrom("107.86.20.132");
builder.aggregation(ip_ranges);
SearchResponse search = server.search(builder, index);
ParsedBinaryRange aggregation =  search.getAggregations().get("ip_ranges");
for (MultiBucketsAggregation.Bucket bucket : aggregation.getBuckets()) {
    
    
    String key = bucket.getKeyAsString();
    long count = bucket.getDocCount();
    System.out.println(key+"="+count);
}

3. 关注我

搜索微信公众号:java架构强者之路
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dwjf321/article/details/103993819