Elasticsearch学习(4) spring boot整合Elasticsearch的聚合操作

  之前已将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();
            }
            
}
bean层代码

三、创建一个dao层

import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;


@Configuration
public interface ZooMapper  extends  ElasticsearchRepository<Zoo,Integer>{

}
dao层代码

四、创建一个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<Aggregations>() {
              @Override
              public Aggregations extract(SearchResponse response) {
                  return response.getAggregations();
              }
          });
          //将aggregations转换成map集合
          Map<String, Aggregation> aggregationMap = aggregations.asMap();
          //得到聚合的值,参数是自己定义的别名
          InternalSum internalSum=(InternalSum) aggregationMap.get("sum_num");
            return internalSum.getValue();    
    }
    
    
}
controller层代码

在测试之前,我们需要在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}
        }  
    } 
}

  

猜你喜欢

转载自www.cnblogs.com/daijiting/p/10219847.html