欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot + elasticsearch 實現(xiàn)聚合查詢的詳細(xì)代碼

 更新時間:2025年02月17日 14:28:47   作者:筆墨登場說說  
文章介紹了如何在Spring Boot 2.2.6中使用Elasticsearch進行聚合查詢,重點在于通過API創(chuàng)建索引和映射,而不是使用Spring Data Elasticsearch的自動創(chuàng)建功能,文章還提到在創(chuàng)建映射時,Elasticsearch會自動為keyword類型添加keyword屬性,感興趣的朋友一起看看吧

需求背景:

終端上報表讀數(shù) 記錄在elasticsearch

統(tǒng)計每天 最大值最小值

springboot版本:2.2.6   

默認(rèn)的elasticsearch

 <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-elasticsearch</artifactId>
      <version>3.2.6.RELEASE</version>

版本 elasticsearch

{
  "name" : "node1",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "Lg0bD-E-Thuaw4cDN5uQrQ",
  "version" : {
    "number" : "7.4.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96",
    "build_date" : "2019-10-28T20:40:44.881551Z",
    "build_snapshot" : false,
    "lucene_version" : "8.2.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

根據(jù)springdata官網(wǎng)

Spring Data Elasticsearch - Reference Documentation

 版本符合

這里為了方便 采用的是 api創(chuàng)建索引

切記這里沒有采用spring-data 去創(chuàng)建索引 而是采用的是 api 接口創(chuàng)建 原因后面再提

    @PutMapping("/createIndex")
    @ApiOperation(value = "創(chuàng)建索引")
    public R<Object> createIndex() {
        boolean index = elasticsearchRestTemplate.createIndex(DataUploadInfo.class);
        elasticsearchRestTemplate.putMapping(DataUploadInfo.class);
        return R.success();
    }
 
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
 *  {
 *   "busId": "1000010814",
 *   "createTime": 1649408879000,
 *   "deviceNum": "AE0007A1GMBC00047P",
 *   "gunNo": "1",
 *   "rdChargeCurrent": 5.617,
 *   "rdChargingPower": 1220.0,
 *   "rdChargingVoltage": 225.11,
 *   "totalElectricalPower": 270305.0
 * }
 *
 *
 *
 * @Field(type=FieldType.Text, analyzer=“ik_max_word”) 表示該字段是一個文本,并作最大程度拆分,默認(rèn)建立索引
 * @Field(type=FieldType.Text,index=false) 表示該字段是一個文本,不建立索引
 * @Field(type=FieldType.Date) 表示該字段是一個文本,日期類型,默認(rèn)不建立索引
 * @Field(type=FieldType.Long) 表示該字段是一個長整型,默認(rèn)建立索引
 * @Field(type=FieldType.Keyword) 表示該字段內(nèi)容是一個文本并作為一個整體不可分,默認(rèn)建立索引
 * @Field(type=FieldType.Float) 表示該字段內(nèi)容是一個浮點類型并作為一個整體不可分,默認(rèn)建立索引
 * <p>
 * date 、float、long都是不能夠被拆分的
 */
@Data
@Document(indexName = "charging-monitor-data", indexStoreType = "_doc", useServerConfiguration = true, createIndex = false)
@TypeAlias("_doc")
public class DataUploadInfo {
    /**
     * 主鍵
     */
    @Id
    @ApiModelProperty(value = "主鍵", example = "11", hidden = true)
    private String id;
    @ApiModelProperty(value = "槍號", example = "1")
    @Field(type = FieldType.Keyword )
    private String gunNo;
    @ApiModelProperty(value = "樁號", example = "DG1120B1CN1C000125")
    @Field(type = FieldType.Keyword)
    private String deviceNum;
    @ApiModelProperty(value = "流水ID", example = "AU22188888888888")
    @Field(type = FieldType.Keyword )
    private String busId;
    @ApiModelProperty(value = "充電電流(毫安)", example = "21.21")
    @Field(type = FieldType.Double, index = false)
    private Double rdChargeCurrent;
    @ApiModelProperty(value = "充電電壓(毫伏)", example = "212.21")
    @Field(type = FieldType.Double, index = false)
    private Double rdChargingVoltage;
    @ApiModelProperty(value = "充電電能(瓦)", example = "212.21")
    @Field(type = FieldType.Double, index = false)
    private Double rdChargingPower;
    @ApiModelProperty(value = "剩余時間(分鐘)", example = "21")
    @Field(type = FieldType.Integer, index = false)
    private Integer rdTimeLeft;
    @ApiModelProperty(value = "電量百分比(soc)", example = "29")
    @Field(type = FieldType.Integer, index = false)
    private Integer rdCurrentSoc;
    @ApiModelProperty(value = "電表讀數(shù) 單位kwh 保留三位小數(shù),啟動成功時才有", example = "2.292")
    @Field(type = FieldType.Double, index = false)
    private Double totalElectricalPower;
    @ApiModelProperty(value = "正極溫度", example = "22")
    @Field(type = FieldType.Integer, index = false)
    private Integer gunPositiveTemperature;
    @ApiModelProperty(value = "負(fù)極溫度", example = "83")
    @Field(type = FieldType.Integer, index = false)
    private Integer gunNegativeTemperature;
    @ApiModelProperty(value = "電量上報時間", example = "1648646486000")
    @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
    private Long createTime;
}

這里是創(chuàng)建 映射的Java文件 注意配置   createIndex = false

這里不自動創(chuàng)建索引

我們調(diào)用上面的rest 接口創(chuàng)建 索引

查看_mapping 會發(fā)現(xiàn)

{
-"charging-monitor-data": {
-"mappings": {
-"properties": {
-"busId": {
"type": "keyword"
},
-"createTime": {
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"type": "date"
},
-"deviceNum": {
"type": "keyword"
},
-"gunNegativeTemperature": {
"index": false,
"type": "integer"
},
-"gunNo": {
"type": "keyword"
},
-"gunPositiveTemperature": {
"index": false,
"type": "integer"
},
-"id": {
-"fields": {
-"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
-"rdChargeCurrent": {
"index": false,
"type": "double"
},
-"rdChargingPower": {
"index": false,
"type": "double"
},
-"rdChargingVoltage": {
"index": false,
"type": "double"
},
-"rdCurrentSoc": {
"index": false,
"type": "integer"
},
-"rdTimeLeft": {
"index": false,
"type": "integer"
},
-"totalElectricalPower": {
"index": false,
"type": "double"
}
}
}
}
}

keyword類型會增加keyword屬性 而不是直接增加到我定義gunNegativeTemperature的屬性下面

"pojo里面定義的屬性": {
   -"fields": {
     -"keyword": {
        "ignore_above": 256,
        "type": "keyword"
      }
    },
   "type": "text"
}

下面按照樁槍做每日電表的最大最小值

上代碼

 
import com.haoran.cloud.app.monitor.entity.DataUploadInfo;
import com.haoran.cloud.app.monitor.ocpp.OcppResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.index.query.BoolQueryBuilder;
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.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.max.MaxAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.max.ParsedMax;
import org.elasticsearch.search.aggregations.metrics.min.MinAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.min.ParsedMin;
import org.joda.time.DateTime;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * @author wenhaoran
 * @version 1.0
 */
@RestController
@RequestMapping("/test")
@Api(value = "test", tags = "test")
@Log4j2
@Validated
public class PileMonitorController1 {
    /**
     * @return
     */
    @GetMapping("/dailySummaryEnergy")
    @ApiOperation(value = "每日電力匯總")
    public OcppResult<Object> dailySummaryEnergy() throws ParseException {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        DateTime now = DateTime.now();
        DateTime plus = now.plusDays(1);
        String fromDateStr = df.format(now.toDate());
        Date fromDate = df.parse(fromDateStr);
        String toDateStr = df.format(plus.toDate());
        Date toDate = df.parse(toDateStr);
        queryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(fromDate.getTime()).lt(toDate.getTime()));
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(queryBuilder);
        TermsAggregationBuilder pile = AggregationBuilders.terms("group_deviceNum").field("deviceNum");
        TermsAggregationBuilder gun = AggregationBuilders.terms("group_gunNo").field("gunNo");
        MinAggregationBuilder minNumber = AggregationBuilders.min("minNumber").field("totalElectricalPower");
        MaxAggregationBuilder maxNumber = AggregationBuilders.max("maxNumber").field("totalElectricalPower");
        gun.subAggregation(minNumber).subAggregation(maxNumber);
        pile.subAggregation(gun);
        nativeSearchQueryBuilder.addAggregation(pile);
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        Aggregations query = elasticsearchRestTemplate.query(nativeSearchQuery, searchResponse -> searchResponse.getAggregations());
        Map<String, Aggregation> stringAggregationMap = query.asMap();
        ParsedStringTerms stringTerms = (ParsedStringTerms) stringAggregationMap.get("group_deviceNum");
        List<? extends Terms.Bucket> buckets = stringTerms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            Map<String, Aggregation> pileMap = bucket.getAggregations().asMap();
            ParsedStringTerms gunAgg = (ParsedStringTerms) pileMap.get("group_gunNo");
            List<? extends Terms.Bucket> gunBucketList = gunAgg.getBuckets();
            for (Terms.Bucket gunBucket : gunBucketList) {
                Aggregations aggregations = gunBucket.getAggregations();
                Map<String, Aggregation> asMap = aggregations.getAsMap();
                if (asMap.containsKey("minNumber")) {
                    ParsedMin aggregation = (ParsedMin) asMap.get("minNumber");
                    System.out.println("minNumber=" + aggregation.getValue());
                }
                if (asMap.containsKey("maxNumber")) {
                    ParsedMax aggregation = (ParsedMax) asMap.get("maxNumber");
                    System.out.println("maxNumber=" + aggregation.getValue());
                }
            }
        }
        return OcppResult.success("success");
    }
    @DeleteMapping("/deleteIndex")
    @ApiOperation(value = "刪除索引")
    public OcppResult<Object> deleteIndex() {
        elasticsearchRestTemplate.deleteIndex(DataUploadInfo.class);
        return OcppResult.success();
    }
    @PutMapping("/createIndex")
    @ApiOperation(value = "創(chuàng)建索引")
    public OcppResult<Object> createIndex() {
        boolean index = elasticsearchRestTemplate.createIndex(DataUploadInfo.class);
        elasticsearchRestTemplate.putMapping(DataUploadInfo.class);
        return OcppResult.success();
    }
    final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
}

到此這篇關(guān)于springboot + elasticsearch 實現(xiàn)聚合查詢的文章就介紹到這了,更多相關(guān)springboot elasticsearch聚合查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot、Java 使用 Jsoup 解析 HTML 頁面的詳細(xì)步驟

    SpringBoot、Java 使用 Jsoup 解析 HTML 頁面

    這篇文章主要介紹了SpringBoot、Java 使用 Jsoup 解析 HTML 頁面的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • mybatis 一對一、一對多和多對多查詢實例代碼

    mybatis 一對一、一對多和多對多查詢實例代碼

    這篇文章主要介紹了mybatis 一對一、一對多和多對多查詢的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • 使用SpringBoot注解方式處理事務(wù)回滾實現(xiàn)

    使用SpringBoot注解方式處理事務(wù)回滾實現(xiàn)

    這篇文章主要介紹了使用SpringBoot注解方式處理事務(wù)回滾實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java如何獲取用戶登錄ip、瀏覽器信息、SessionId

    java如何獲取用戶登錄ip、瀏覽器信息、SessionId

    這篇文章主要介紹了java如何獲取用戶登錄ip、瀏覽器信息、SessionId,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 并發(fā)編程模式之ThreadLocal源碼和圖文解讀

    并發(fā)編程模式之ThreadLocal源碼和圖文解讀

    這篇文章主要介紹了并發(fā)編程模式之ThreadLocal源碼和圖文解讀,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Struts2實現(xiàn)CRUD(增 刪 改 查)功能實例代碼

    Struts2實現(xiàn)CRUD(增 刪 改 查)功能實例代碼

    CRUD是Create(創(chuàng)建)、Read(讀?。pdate(更新)和Delete(刪除)的縮寫,它是普通應(yīng)用程序的縮影。接下來通過本文給大家介紹Struts2實現(xiàn)CRUD(增 刪 改 查)功能實例代碼,感興趣的朋友一起看看吧
    2016-06-06
  • Java AOP實現(xiàn)自定義滑動窗口限流器方法詳解

    Java AOP實現(xiàn)自定義滑動窗口限流器方法詳解

    這篇文章主要介紹了Java AOP實現(xiàn)自定義滑動窗口限流器方法,其中滑動窗口算法彌補了計數(shù)器算法的不足,滑動窗口算法把間隔時間劃分成更小的粒度,當(dāng)更小粒度的時間間隔過去后,把過去的間隔請求數(shù)減掉,再補充一個空的時間間隔,需要的朋友可以參考下
    2022-07-07
  • Java中的自定義異常實現(xiàn)方式

    Java中的自定義異常實現(xiàn)方式

    這篇文章主要介紹了Java中的自定義異常實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • java序列化對象根據(jù)不同配置動態(tài)改變屬性名的方法

    java序列化對象根據(jù)不同配置動態(tài)改變屬性名的方法

    本文主要介紹了java序列化對象根據(jù)不同配置動態(tài)改變屬性名的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 詳解Elasticsearch如何實現(xiàn)簡單的腳本排序

    詳解Elasticsearch如何實現(xiàn)簡單的腳本排序

    Elasticsearch?是位于?Elastic?Stack?核心的分布式搜索和分析引擎,可以為所有類型的數(shù)據(jù)提供近乎實時的搜索和分析。本文主要介紹了Elasticsearch如何實現(xiàn)簡單的腳本排序,感興趣的可以了解一下
    2023-01-01

最新評論