概述
city-event-processing——索引名
一、数据体
索引结构
PUT city-event-processing
{
"settings": {
"number_of_shards": 10,
"number_of_replicas": 1,
"refresh_interval": "1s"
},
"mappings": {
"properties": {
"address": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"caseNumber": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"causeId": {
"type": "keyword"
},
"createTime": {
"type": "date",
"format": "epoch_millis"
},
"updateTime": {
"type": "date",
"format": "epoch_millis"
},
"deviceId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"deviceName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"autoCheckPass": {
"type": "boolean"
},
"location": {
"type": "geo_point"
},
"state": {
"type": "integer"
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"acceptType": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"videoId": {
"type": "keyword"
}
}
}
}
数据体
/**
* @param
* @Author zhangwei
* @Date 2021/3/23
* @Description 告警事件数据库结构
*/
@AllArgsConstructor
@Data
public class AlarmEventPO {
/**
* 目标Id
*/
private String causeId;
/**
* 案件编号
*/
private String caseNumber;
/**
* 视频Id
*/
private String videoId;
/**
* 告警地点
*/
private String address;
/**
* 告警地点坐标
*/
private Coordinate location;
/**
* 告警类型
*/
private String type;
/**
* 接受的告警类型
*/
private String acceptType;
/**
* 告警时间
*/
private Long createTime;
/**
* 自动核查是否通过
*/
private Boolean autoCheckPass;
/**
* 案件状态
*/
private Integer state;
/**
* 数据更新时间
*/
private Long updateTime;
/**
* 设备Id
*/
private String deviceId;
}
二、简单查询
2.1、精准查询某单个案件编号的案件
注:caseNumber为text类型,caseNumber.keyword为keyword类型
2.1.1、DSL语句
GET city-event-processing/_search
{
"query": {
"term": {
"caseNumber.keyword": {
"value": "2104231001042"
}
}
}
}
2.1.2、RestHighLevelClient实现
/**
* @description: 根据案件号查询事件信息
* @param:
* @return:
* @date: 2020/2/25
*/
@Override
public Optional<AlarmEventPO> selectAlarmEventByCaseNumber(final String caseNumber) {
/** 构造查询Request **/
final QueryBuilder queryBuilder = QueryBuilders.termQuery(“caseNumber.keyword”, caseNumber);
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder).size(1);
final SearchRequest request = Requests.searchRequest(“city-event-processing”).source(searchSourceBuilder);
try {
/** 查询 **/
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
RestStatus restStatus = response.status();
if (restStatus != RestStatus.OK) {
throw CommonError.ES_ERROR.exception();
}
if (response.getHits().getHits().length == 0L) {
return Optional.empty();
} else {
return Arrays.stream(response.getHits().getHits())
.map(hit -> JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class)).findFirst();
}
} catch (IOException e) {
log.error("elastic search failed to search event, caseNumber:[{}]", caseNumber);
throw CommonError.ES_ERROR.exception(e);
}
}
2.2、精准查询某些案件编号的案件
注:caseNumber为text类型,caseNumber.keyword为keyword类型
2.1.1、DSL语句
GET city-event-processing/_search
{
"query": {
"terms": {
"caseNumber.keyword": [
"2104231001042", "2104231001056"
]
}
}
}
2.1.2、RestHighLevelClient实现
/**
* @description: 根据案件号查询事件信息
* @param:
* @return:
* @date: 2020/2/25
*/
@Override
public List<AlarmEventPO> selectAlarmEventByCaseNumber(final String[] caseNumbers) {
/** 构造查询Request **/
final QueryBuilder queryBuilder = QueryBuilders.termsQuery(“caseNumber.keyword”, caseNumbers);
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder).size(1);
final SearchRequest request = Requests.searchRequest(“city-event-processing”).source(searchSourceBuilder);
try {
/** 查询 **/
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
RestStatus restStatus = response.status();
if (restStatus != RestStatus.OK) {
throw CommonError.ES_ERROR.exception();
}
if (response.getHits().getHits().length == 0L) {
return Collections.emptyList();
} else {
return Arrays.stream(response.getHits().getHits())
.map(hit -> JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class)).collect(Collectors.toList());
}
} catch (IOException e) {
log.error("elastic search failed to search event, caseNumber:[{}]", caseNumber);
throw CommonError.ES_ERROR.exception(e);
}
}
2.3、查询state为特定值或者state为某些值的案件
注:state为Integer类型
2.3.1、DSL
state为特定值
GET city-event-processing/_search
{
"query": {
"terms": {
"state": [1]
}
}
}
state为某些值
GET city-event-processing/_search
{
"query": {
"terms": {
"state": [1,2]
}
}
}
2.3.2、RestHighLevelClient实现
state为特定值
/**
* @description: 根据state状态查询事件信息
* @param:
* @return:
* @date: 2020/2/25
*/
@Override
public List<AlarmEventPO> selectAlarmEventByState(final Integer state) {
/** 构造查询Request **/
final QueryBuilder queryBuilder = QueryBuilders.termQuery("state", state);
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder);
final SearchRequest request = Requests.searchRequest(“city-event-processing”).source(searchSourceBuilder);
try {
/** 查询 **/
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
if (response.getHits().getHits().length == 0L) {
return Optional.empty();
} else {
return Arrays.stream(response.getHits().getHits())
.map(hit -> JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class)).collect(Collectors.toList());
}
} catch (IOException e) {
log.error("elastic search failed to search event, caseNumber:[{}]", caseNumber);
throw CommonError.ES_ERROR.exception(e);
}
}
state为某些值
/**
* @description: 根据state状态查询事件信息
* @param:
* @return:
* @date: 2020/2/25
*/
@Override
public List<AlarmEventPO> selectAlarmEventByState(final Integer[] states) {
/** 构造查询Request **/
final QueryBuilder queryBuilder = QueryBuilders.termsQuery("state", states);
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder);
final SearchRequest request = Requests.searchRequest(“city-event-processing”).source(searchSourceBuilder);
try {
/** 查询 **/
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
if (response.getHits().getHits().length == 0L) {
return Optional.empty();
} else {
return Arrays.stream(response.getHits().getHits())
.map(hit -> JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class)).collect(Collectors.toList());
}
} catch (IOException e) {
log.error("elastic search failed to search event, caseNumber:[{}]", caseNumber);
throw CommonError.ES_ERROR.exception(e);
}
}
2.4、范围查询,这里以createTime字段实验
2.4.1、DSL
GET city-event-processing/_search
{
"query": {
"range": {
"createTime": {
"gte": 1617762286042,
"lte": 1617762286042
}
}
}
}
gte:大于等于
lte:小于等于
gt:大于
lt:小于
2.4.2、RestHighLevelClient实现
/**
* @description: 根据createTime范围查询事件信息
* @param:startTime 起始时间 endTime 结束时间
* @return:
* @date: 2020/2/25
*/
@Override
public List<AlarmEventPO> selectAlarmEventByTime(final Long startTime, final Long endTime) {
/** 构造查询Request **/
final QueryBuilder queryBuilder = QueryBuilders.rangeQuery(CREATE_TIME_KEY).gte(startTime).lte(endTime);
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder);
final SearchRequest request = Requests.searchRequest(“city-event-processing”).source(searchSourceBuilder);
try {
/** 查询 **/
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
if (response.getHits().getHits().length == 0L) {
return Optional.empty();
} else {
return Arrays.stream(response.getHits().getHits())
.map(hit -> JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class)).collect(Collectors.toList());
}
} catch (IOException e) {
log.error("elastic search failed to search event, caseNumber:[{}]", caseNumber);
throw CommonError.ES_ERROR.exception(e);
}
}
2.5、多查询条件——与/且关系
时间范围查询(createTime)与(&&)案件号(caseNumber)前缀模糊查询
2.5.1、DSL
GET city-event-processing/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"caseNumber.keyword": {
"value": "210508"
}
}
},
{
"range": {
"createTime": {
"gte": 1619798400000,
"lte": 1651115440000
}
}
}
]
}
}
}
2.5.2、RestHighLevelClient实现
package com.elasticsearch.elasticsearchlearning.dao.impl;
import com.alibaba.fastjson.JSON;
import com.elasticsearch.elasticsearchlearning.constant.CommonConstant;
import com.elasticsearch.elasticsearchlearning.constant.CommonError;
import com.elasticsearch.elasticsearchlearning.dao.BaseElasticSearchDao;
import com.elasticsearch.elasticsearchlearning.dao.IAlarmEventDao;
import com.elasticsearch.elasticsearchlearning.modle.po.AlarmEventPO;
import com.elasticsearch.elasticsearchlearning.query.BaseEventPageQuery;
import com.elasticsearch.elasticsearchlearning.query.BaseEventQuery;
import com.elasticsearch.elasticsearchlearning.utils.Page;
import com.elasticsearch.elasticsearchlearning.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.megvii.framework.util.StringUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @param
* @Author zhangwei
* @Date 2021/4/29
* @Description 案件dao
*/
@Slf4j
@Repository
public class AlarmEventDao extends BaseElasticSearchDao implements IAlarmEventDao {
private static final String CASE_NUMBER_KEY = "caseNumber.keyword";
private static final String CREATE_TIME_KEY = "createTime";
//索引名
private static final String INDEX_NAME = "city-event-processing";
/**
* 根据基础query查询案件
* @param pageQuery
* @return
*/
@Override
public List<AlarmEventPO> selectAlarmEventPOByBasePageQuery(BaseEventQuery pageQuery) {
BoolQueryBuilder boolQueryBuilder = buildQueryBuilderByBaseEventQuery(pageQuery);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(boolQueryBuilder);
final SearchRequest request = Requests.searchRequest(INDEX_NAME).source(sourceBuilder);
final List<AlarmEventPO> results = new ArrayList<>();
try {
// 处理结果
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
RestStatus restStatus = response.status();
if (restStatus != RestStatus.OK) {
throw CommonError.ES_ERROR.exception();
}
for (SearchHit hit : response.getHits().getHits()) {
final AlarmEventPO result = JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class);
results.add(result);
}
} catch (IOException e) {
throw CommonError.ES_ERROR.exception(e);
}
return results;
}
private BoolQueryBuilder buildQueryBuilderByBaseEventQuery(BaseEventQuery query) {
BoolQueryBuilder result = QueryBuilders.boolQuery();
//根据案件号前模糊过滤
String caseNumber = query.getCaseNumber();
if (StringUtil.isNotEmpty(caseNumber)) {
QueryBuilder builder = QueryBuilders.prefixQuery(CASE_NUMBER_KEY, caseNumber);
result.must(builder);
}
Long startTime = query.getStartTime();
//根据产生时间进行筛选
if (null != startTime) {
QueryBuilder builder = QueryBuilders.rangeQuery(CREATE_TIME_KEY).gte(startTime);
result.must(builder);
}
Long endTime = query.getStartTime();
if (null != endTime) {
QueryBuilder builder = QueryBuilders.rangeQuery(CREATE_TIME_KEY).lte(endTime);
result.must(builder);
}
return result;
}
}
2.6、多查询条件并分页——或关系
**案件号(caseNumber)前缀模糊查询(记为A),时间范围查询(createTime)(记为B),地址全模糊查询(记为C) **
实现:A && (B || C)——A必须满足,B、C至少满足一个且实现分页
2.6.1、DSL实现
GET city-event-processing/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"caseNumber.keyword": {
"value": "210517"
}
}
}
],
"should": [
{
"range": {
"createTime": {
"gte": 1621224018000,
"lte": 1621245618000
}
}
},
{
"wildcard": {
"address.keyword": {
"value": "*"
}
}
}
],
"minimum_should_match": 1
}
},
"from": 100,
"size": 20
}
2.6.2、RestHighLevelClient实现
public Page<AlarmEventPO> selectAlarmShouldTest(BaseEventQuery pageQuery) {
String caseNumber = pageQuery.getCaseNumber();
Long startTime = pageQuery.getStartTime();
Long endTime = pageQuery.getEndTime();
Integer pageNo = pageQuery.getPageNo();
Integer pageSize = pageQuery.getPageSize();
int from = pageSize * (pageNo - 1);
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
/*根据案件号前模糊查询*/
queryBuilder.must(QueryBuilders.prefixQuery(CASE_NUMBER_KEY, caseNumber));
/*根据时间进行范围查询*/
queryBuilder.should(QueryBuilders.rangeQuery(CREATE_TIME_KEY).gte(startTime).lte(endTime));
/*根据地址全模糊查询*/
queryBuilder.should(QueryBuilders.wildcardQuery(ADDRESS_KEY, "*友谊路*"));
/*should条件至少满足一个*/
queryBuilder.minimumShouldMatch(1);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().from(from).size(pageSize).query(queryBuilder);
final SearchRequest request = Requests.searchRequest(INDEX_NAME).source(sourceBuilder);
final List<AlarmEventPO> results = new ArrayList<>();
/*构造分页builder*/
PageUtil.PageBuilder pageBuilder = PageUtil.of(pageNo, pageSize, CommonConstant.MAX_RESULT_WINDOW);
long totalCounts;
try {
// 处理结果
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
RestStatus restStatus = response.status();
if (restStatus != RestStatus.OK) {
throw CommonError.ES_ERROR.exception();
}
for (SearchHit hit : response.getHits().getHits()) {
final AlarmEventPO result = JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class);
results.add(result);
}
totalCounts = getDocTotalCount(response.getHits().getTotalHits() , queryBuilder, INDEX_NAME);
} catch (IOException e) {
throw CommonError.ES_ERROR.exception(e);
}
return pageBuilder.build(totalCounts, results);
}
/**
* @Author zhangwei
* @Date 2021/3/26 18:59
* @Description 根据查询条件算出总记录数
*/
@SneakyThrows
protected Long getDocTotalCount(QueryBuilder boolQueryBuilder, String... indices) {
CountRequest countRequest = new CountRequest(indices);
countRequest.query(boolQueryBuilder);
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
}
/**
* TotalHits的relation为EQUAL_TO时,totalHits.value数量即为总数量
*/
public long getDocTotalCount(TotalHits totalHits, QueryBuilder boolQueryBuilder, String... index){
if (TotalHits.Relation.EQUAL_TO == totalHits.relation) {
return totalHits.value;
} else {
return getDocTotalCount(boolQueryBuilder, index);
}
}
2.7、某查询条件下数量查询
2.7.1、DSL实现
GET city-event-processing/_count
{
"query": {
"bool": {
"must": [
{
"term": {
"state": {
"value": 1
}
}
}
]
}
}
}
2.7.2、RestHighLevelClient实现
/**
* @Author zhangwei
* @Date 2021/3/26 18:59
* @Description 根据查询条件算出总记录数
*/
@SneakyThrows
protected Long getDocTotalCount(QueryBuilder boolQueryBuilder, String... indices) {
CountRequest countRequest = new CountRequest(indices);
countRequest.query(boolQueryBuilder);
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
}
2.8、searchAfter分页查询
2.8.1、searchAfter的运用场景
1、查询时会根据某个或某些字段进行排序。
2、排序后,查询排序字段某单边范围的数据。例如:按号码进行升序排序,查询大于等于1000的数据。
2.8.2、DSL实现
GET city-event-processing/_search
{
"query": {
"match_all": {}
},
"search_after":[
"2105211000799"
],
"from": 5,
"size": 10,
"sort": [
{
"caseNumber.keyword": {
"order": "asc"
}
}
]
}
2.8.3、RestHighLevelClient实现
/**
* searchAfter分页查询测试
* @param pageQuery
* @return
*/
public Page<AlarmEventPO> selectAlarmSearchAfterTest(BaseEventQuery pageQuery) {
Integer pageNo = pageQuery.getPageNo();
Integer pageSize = pageQuery.getPageSize();
int from = pageSize * (pageNo - 1);
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().from(from).size(pageSize).query(queryBuilder);
//按案件号进行排序
sourceBuilder.sort(CASE_NUMBER_KEY, SortOrder.ASC);
//大于某案件号分页查询
sourceBuilder.searchAfter(new String[]{pageQuery.getCaseNumber()});
final SearchRequest request = Requests.searchRequest(INDEX_NAME).source(sourceBuilder);
final List<AlarmEventPO> results = new ArrayList<>();
/*构造分页builder*/
PageUtil.PageBuilder pageBuilder = PageUtil.of(pageNo, pageSize, CommonConstant.MAX_RESULT_WINDOW);
long totalCounts;
try {
// 处理结果
final SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
RestStatus restStatus = response.status();
if (restStatus != RestStatus.OK) {
throw CommonError.ES_ERROR.exception();
}
for (SearchHit hit : response.getHits().getHits()) {
final AlarmEventPO result = JSON.parseObject(hit.getSourceAsString(), AlarmEventPO.class);
results.add(result);
}
totalCounts = getDocTotalCount(response.getHits().getTotalHits() , queryBuilder, INDEX_NAME);
} catch (IOException e) {
throw CommonError.ES_ERROR.exception(e);
}
return pageBuilder.build(totalCounts, results);
}
/**
* @Author zhangwei
* @Date 2021/3/26 18:59
* @Description 根据查询条件算出总记录数
*/
@SneakyThrows
protected Long getDocTotalCount(QueryBuilder boolQueryBuilder, String... indices) {
CountRequest countRequest = new CountRequest(indices);
countRequest.query(boolQueryBuilder);
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
}
/**
* 在totalHits.relation为EQUAL_TO时,此时的value就是查询的总数
* 查询统计数量
*/
public long getDocTotalCount(TotalHits totalHits, QueryBuilder boolQueryBuilder, String... index){
if (TotalHits.Relation.EQUAL_TO == totalHits.relation) {
return totalHits.value;
} else {
return getDocTotalCount(boolQueryBuilder, index);
}
}
最后
以上就是温暖星月为你收集整理的ElasticSearch学习笔记(三):CRUD之简单查询的全部内容,希望文章能够帮你解决ElasticSearch学习笔记(三):CRUD之简单查询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复