今天对着ES官方文档尝试使用聚合,但是在使用过程中出现了异常。异常如下:
ElasticsearchStatusException[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [color] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [color] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]];
由于我索引的文档是如下,字段默认设置的是text
POST /cars/transactions/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }
ES中有一个fielddata的参数默认为false未启用,因为fielddata会消耗大量的堆内存,特别是当加载大量的text字段时;fielddata一旦加载到堆中,在segment的生命周期之内都将一致保持在堆中,另外加载fielddata也是一个比较耗时的过程,这可能会导致用户遇到延迟,故而默认情况下禁用fielddata参数;
若尝试针对text字段进行聚合操作时,将会抛出以下异常:
可以在创建索引时设置字段映射添加此属性,不过不推荐使用。
由于text类型的字段自带一个类型为keyword的子字段,可以使用此字段进行排序和聚合。通过Kibana查看可以发现:
java代码如下
@Test
public void aagsTest() throws IOException {
//创建查询请求
SearchRequest request = new SearchRequest();
//构建查询创建者
SearchSourceBuilder ssb = new SearchSourceBuilder();
//添加聚合条件
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.
terms("popular_colors").//设置一个桶的名字 取结果的时候需要用到
field("color.keyword"); // 聚合的字段 color类型为text 取类型为keyword的子字段color.keyword
ssb.aggregation(aggregationBuilder);
request.indices("cars");
request.source(ssb);
//执行查询返回查询响应结果
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//取结果
Terms aggs = search.getAggregations().get("popular_colors");
for (Terms.Bucket bucket : aggs.getBuckets()) {
System.out.println(bucket.getKeyAsString());
}
}
输出结果