之前已将spring boot原生方式介绍了,接下将结介绍的是Elasticsearch聚合操作。聚合操作一般来说是解决一下复杂的业务,比如mysql中的求和和分组,由于博主踩的坑比较多,所以博客可能更多的会介绍这些坑。
一、application.properties配置文件
##端口号 server.port=8880 ##es地址 spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300
二、创建一个Bean层
import org.springframework.data.elasticsearch.annotations.Document; @Document(indexName = "article",type = "center") public class Zoo { private int id; private String animal; private Integer num; private String breeder; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAnimal() { return animal; } public void setAnimal(String animal) { this.animal = animal; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getBreeder() { return breeder; } public void setBreeder(String breeder) { this.breeder = breeder; } public Zoo(int id, String animal, Integer num, String breeder) { super(); this.id = id; this.animal = animal; this.num = num; this.breeder = breeder; } public Zoo() { super(); } }
三、创建一个dao层
import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @Configuration public interface ZooMapper extends ElasticsearchRepository{ }
四、创建一个Controller层,编写聚合代码
import java.util.Map; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.metrics.sum.InternalSum; import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired ZooMapper zooMapper; @Autowired private ElasticsearchTemplate elasticsearchTemplate; // 访问接口地址:localhost:8880/find //存储数据 @GetMapping("find") public Object save(){ //创建查询条件,这里表示查询所有文档 QueryBuilder queryBuilder=QueryBuilders.boolQuery(); //构造sql组装容器 NativeSearchQueryBuilder nativeSearchQueryBuilder =new NativeSearchQueryBuilder(); //创建聚合条件,求和函数 SumAggregationBuilder sumAgg = AggregationBuilders.sum("sum_num").field("num"); //将查询条件和聚合条件放入sql组装容器中 nativeSearchQueryBuilder.withQuery(queryBuilder); nativeSearchQueryBuilder.addAggregation(sumAgg); //封装sql组装容器 SearchQuery query = nativeSearchQueryBuilder.build(); //执行sql,此时容器中的sql1为 //select SUM(num) from zoo Aggregations aggregations = elasticsearchTemplate.query(query, new ResultsExtractor() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); //将aggregations转换成map集合 Map aggregationMap = aggregations.asMap(); //得到聚合的值,参数是自己定义的别名 InternalSum internalSum=(InternalSum) aggregationMap.get("sum_num"); return internalSum.getValue(); } }
在测试之前,我们需要在ES中添加索引:
访问 localhost:8880/find
本文只介绍了求和的聚合方式,至于其他聚合方式可以参考:
http://blog.csdn.net/u010454030/article/details/63266035
五、遇到的问题
ES中text类型无法聚合问题,错误代码:
java.lang.IllegalArgumentException: Fielddata is disabled on text fields by default. Set fielddata=true on [geoip.city_name] in order to load fielddata in memory by uninverting the inverted index.
Note that this can however use significant memory. Alternatively use a keyword field instead.at org.elasticsearch.index.mapper.TextFieldMapper$TextFieldType.fielddataBuilder(TextFieldMapper.java:336)
解决方案:
通过get请求地址:http://127.0.0.1:9200/你的索引名/你的type名/_search
参数为:
{"你的type名字": {"properties": {"你要设置的字段名": {"type":"text","fielddata":true} } } }