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}
        }  
    } 
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM