Elasticsearch支持最直方图聚合,它在数字字段自动建立桶,并会扫描所有文档,把文档放入相应的桶中。这个数字字段既能够是文档中的某个字段,也能够经过脚本建立得出的。数组
举个例子,有一个price字段,这个字段描述了商品的价格,如今想每隔5就建立一个桶,统计每隔区间都有多少个文档(商品)。code
若是有一个商品的价格为32,那么它会被放入30的桶中,计算的公式以下:排序
rem = value % interval if (rem < 0) { rem += interval } bucket_key = value - rem
经过上面的方法,就能够肯定文档属于哪个桶。rem
不过也有一些问题存在,因为上面的方法是针对于整型数据的,所以若是字段是浮点数,那么须要先转换成整型,再调用上面的方法计算。问题来了,正数还好,若是该值是负数,就会出现计算出错。好比,一个字段的值为-4.5,在进行转换整型时,转换成了-4。那么按照上面的计算,它就会放入-4的桶中,可是其实-4.5应该放入-6的桶中。文档
聚合的dsl以下:it
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50 } } } }
获得的数据为:io
{ "aggregations": { "prices" : { "buckets": [ { "key": 0, "doc_count": 2 }, { "key": 50, "doc_count": 4 }, { "key": 100, "doc_count": 0 }, { "key": 150, "doc_count": 3 } ] } } }
上面的数据中,100-150是没有文档的,可是却显示为0.若是不想要显示count为0的桶,能够经过min_doc_count来设置。ast
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50, "min_doc_count" : 1 } } } }
这样返回的数据,就不会出现为0的了。方法
{ "aggregations": { "prices" : { "buckets": [ { "key": 0, "doc_count": 2 }, { "key": 50, "doc_count": 4 }, { "key": 150, "doc_count": 3 } ] } } }
默认状况下,ES中的histogram聚合起始都是自动的,好比price字段,若是没有商品的价钱在0-5之间,0这个桶就不会显示。若是最便宜的商品是11,那么第一个桶就是10.
能够经过设置extend_bounds强制规定最小值和最大值,可是要求必须min_doc_count不能大于0,否则即使是规定了边界,也不会返回。im
另外须要注意的是,若是规定的extend_bounds.min要大于文档中的最小值,那么就会按照文档中的最小值来(extend_bounds.max也是如此)。
好比下面的这个例子,规定的extend_bounds.min和max分别是40和50,可是文档中含有比40还要小的数据,所以桶的定义仍然是按照文档中的数据来。
排序大同小异,能够按照_key的名字排序:
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50, "order" : { "_key" : "desc" } } } } }
也能够按照文档的数目:
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50, "order" : { "_count" : "asc" } } } } }
或者指定排序的聚合:
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50, "order" : { "price_stats.min" : "asc" } }, "aggs" : { "price_stats" : { "stats" : {} } } } } }
正常返回的数据如上面所示,是按照数组的方式返回。若是要按照名字返回,能够设置keyed为true
{ "aggs" : { "prices" : { "histogram" : { "field" : "price", "interval" : 50, "keyed" : true } } } }
那么返回的数据就为:
{ "aggregations": { "prices": { "buckets": { "0": { "key": 0, "doc_count": 2 }, "50": { "key": 50, "doc_count": 4 }, "150": { "key": 150, "doc_count": 3 } } } } }
缺省值经过MissingValue设置:
{ "aggs" : { "quantity" : { "histogram" : { "field" : "quantity", "interval": 10, "missing": 0 } } } }