前两天分组查ES中的数据,给我难为的啊。。网上好多例子,总是不尽人意,最主要的是我刚接触,啥都不懂。如今小有成就,记录备份一下:
业务场景:控制端数据表中,存有管理员的数据,我要根据管理员来分组,查询出有几个管理员。
实体类:注意:需要分组查询的字段类型,要用@Field(type = FieldType.Keyword) 用Keyword类型
package com.elasticsearch.document;
import java.util.Date;
import javax.persistence.Id;
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;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
@Document(indexName = "resource_console", type = "console_info", shards = 1, replicas = 0)
public class ConsoleInfoEs {
@Id
private Long id;
@Field(type = FieldType.Text)
private String consoleName; //控制端名
@Field(type = FieldType.Text)
private String areaCode; //地区代码
@Field(type = FieldType.Keyword)
private String areaName; //地区名
@Field(type = FieldType.Text)
private String companyCode; //公司代码
@Field(type = FieldType.Keyword)
private String companyName; //公司名
@Field(type = FieldType.Keyword)
private String adminCode; //管理员代码
@Field(type = FieldType.Text)
private String adminName; //管理员姓名
@Field(type = FieldType.Text)
private String adminPhone; //管理员联系电话
@Field(type = FieldType.Text)
private String status; //终端状态(0:[新建]未激活,1:在线,2:离线)
@Field(type = FieldType.Text)
private String token; //验证TOKEN
@Field(type = FieldType.Keyword)
private String ip; //IP地址
@Field(type = FieldType.Text)
private String version; //当前版本
@Field(type = FieldType.Text)
private String location; //所在位置
@Field(type = FieldType.Text)
private String deleteFlag; //'0' 删除标识(0:未删除,1:已删除)
@Field(type = FieldType.Text)
private String createBy; //创建人
@Field( type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date createDate; //创建时间
@Field(type = FieldType.Text)
private String updateBy; //更新人
@Field( type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date updateDate; //更新时间
@Field( type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date upgradeDate; //升级时间
@Field(type = FieldType.Keyword)
private String isSucceeded; //是否升级成功(1:是,0:否)
}
package com.common.base;
import lombok.Builder;
import lombok.Data;
/**
* 响应结果
* @param 响应数据类型
*/
@Data
@Builder
public class ResponseResult {
public static final String SUCCESS_CODE = "1";
public static final String ERROR_CODE = "0";
public static final String SUCCESS_MESSAGE = "success";
public static final String ERROR_MESSAGE = "error";
/** 状态码 */
private String code;
/** 响应消息 */
private String message;
/** 响应结果 */
private T data;
/**
* 创建响应结果
*
* @param
* @param code
* @param message
* @param data
* @return
*/
@SuppressWarnings("unchecked")
public static ResponseResult of(String code, String message, T data) {
return (ResponseResult) ResponseResult.builder().code(code).message(message).data(data).build();
}
/**
* 创建响应结果
*
* @param
* @param code
* @param message
* @param data
* @return
*/
public static ResponseResult of(String code, String message) {
return of(code, message, null);
}
/**
* 成功
*
* @param
* @return
*/
public static ResponseResult success() {
return of(SUCCESS_CODE, SUCCESS_MESSAGE);
}
/**
* 成功
*
* @param
* @return
*/
public static ResponseResult success(T data) {
return of(SUCCESS_CODE, SUCCESS_MESSAGE, data);
}
/**
* 失败
*
* @param
* @return
*/
public static ResponseResult error() {
return of(ERROR_CODE, ERROR_MESSAGE);
}
/**
* 失败
*
* @param
* @return
*/
public static ResponseResult error(T data) {
return of(ERROR_CODE, ERROR_MESSAGE, data);
}
}
实体有了,在elasticsearch里生成表,插入数据、查询数据(可能方法存在错误,临时拼凑的,仅供参考)
package com.yltd.sams.controller.es;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.repository.CrudRepository;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yltd.sams.common.base.ResponseResult;
import com.yltd.sams.elasticsearch.document.ConsoleInfoEs;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping(value = "/es/realtime_homepage", produces = MediaType.APPLICATION_JSON_VALUE)
public class Test {
@Autowired
private static ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private static CrudRepository crudRepository;
@Autowired
private static Client client;
//主入口
public static void main(String[] args) {
//创建索引
createIndex();
log.info("============================");
//创建查询索引,参数resource_console表示要查询的索引库为resource_console
SearchResponse searchResponse = client.prepareSearch("resource_console")
.addAggregation(AggregationBuilders.terms("adminCode_count").field("adminCode")
)
.execute().actionGet();
// 执行搜索,返回搜索响应信息
StringTerms adminCode_count = (StringTerms)searchResponse.getAggregations().asMap().get("adminCode_count");
long controlEndUser = adminCode_count.getBuckets().size();
System.out.println(controlEndUser);
log.info("============================");
}
//创建索引
public static ResponseResult
SearchResponse searchResponse = client.prepareSearch("resource_console")
.addAggregation(AggregationBuilders.terms("adminCode_count").field("adminCode")
) .execute().actionGet();
//创建查询索引,参数resource_console表示要查询的索引库为resource_console,聚合的字段是adminCode 起个别名:adminCode_count
得到的数据:
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"_clusters":{"total":0,"successful":0,"skipped":0},"hits":{"total":5,"max_score":1.0,"hits":[{"_index":"resource_console","_type":"console_info","_id":"1","_score":1.0,"_source":{"id":1,"consoleName":"网络端","areaCode":"bbbbb","areaName":"地区9","companyCode":"20001","companyName":"地区2分公司","adminCode":"1","adminName":"张鑫","adminPhone":"1316137","status":"0","token":"TOKEN","ip":"192.168.1.1","version":null,"location":"控制端描述","deleteFlag":null,"createBy":null,"createDate":"2020-05-26 16:34:26","updateBy":null,"updateDate":null,"upgradeDate":null,"isSucceeded":null}},{"_index":"resource_console","_type":"console_info","_id":"2","_score":1.0,"_source":{"id":2,"consoleName":"网络端","areaCode":"aaa","areaName":"地区999","companyCode":"10002","companyName":"分公司12345","adminCode":"1","adminName":"张鑫","adminPhone":"1316137","status":"0","token":"TOKEN","ip":"192.168.1.1","version":null,"location":"描述","deleteFlag":null,"createBy":null,"createDate":"2020-05-26 16:35:15","updateBy":null,"updateDate":null,"upgradeDate":null,"isSucceeded":null}},{"_index":"resource_console","_type":"console_info","_id":"3","_score":1.0,"_source":{"id":3,"consoleName":"控制端","areaCode":"aaa","areaName":"地区999","companyCode":"10006","companyName":"77","adminCode":"2","adminName":"yixin","adminPhone":"131613729","status":"0","token":"TOKEN","ip":"192.168.1.1","version":null,"location":"描述","deleteFlag":null,"createBy":null,"createDate":"2020-05-26 16:36:21","updateBy":null,"updateDate":null,"upgradeDate":null,"isSucceeded":null}},{"_index":"resource_console","_type":"console_info","_id":"4","_score":1.0,"_source":{"id":4,"consoleName":"控制端111","areaCode":"aaa","areaName":"地区999","companyCode":"AjRIJv","companyName":"99999","adminCode":"2","adminName":"yixin","adminPhone":"131613729","status":"0","token":"TOKEN","ip":"192.168.1.1","version":null,"location":"描述","deleteFlag":null,"createBy":null,"createDate":"2020-05-26 16:36:48","updateBy":null,"updateDate":null,"upgradeDate":null,"isSucceeded":null}},{"_index":"resource_console","_type":"console_info","_id":"5","_score":1.0,"_source":{"id":5,"consoleName":"控制端111","areaCode":"aaa","areaName":"地区999","companyCode":"TkXomV","companyName":"6666","adminCode":"2","adminName":"yixin","adminPhone":"131613729","status":"0","token":"TOKEN","ip":"192.168.1.1","version":null,"location":"描述111","deleteFlag":null,"createBy":null,"createDate":"2020-05-26 16:37:05","updateBy":null,"updateDate":null,"upgradeDate":null,"isSucceeded":null}}]},"aggregations":{"adminCode_count":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"2","doc_count":3},{"key":"1","doc_count":2}]}}}
StringTerms adminCode_count = (StringTerms)searchResponse.getAggregations().asMap().get("adminCode_count");
获取json串中的 "aggregations":{"adminCode_count":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"2","doc_count":3},{"key":"1","doc_count":2}]}} 数据。
long controlEndUser = adminCode_count.getBuckets().size();
就是获得json串中的"buckets":[{"key":"2","doc_count":3},{"key":"1","doc_count":2} 数据,总和是2