从ES分页查询数据实例代码(JAVA)
最近做的项目中,为了减轻数据库的压力,许多查询接口都改为走ES去查,而不是直接查MySQL。
当然不是所有的查询都要走ES,还是根据你的业务来,对实时性要求不高的,可以走ES查,如果实时性要求很高,还是建议走MySQL去查。
我的项目工程是SpringBoot工程:
POM文件增加es的依赖:
<!-- elasticsearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
SpringBoot启动时需要加载配置:
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/**
* @author gaopeng
* @date:2020-09-09
*/
@Configuration
public class ESConfig {
/**
* 解决netty引起的issue
*/
@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
}
配置文件增加:
########### Elasticsearch 配置 ##########
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 10.1.2.32:9300
Controller层:
/**
* 根据关键词从ES查询合同分页列表
*/
@GetMapping("/getContractListFromES")
@ApiOperation("合同分页列表")
public ApiResult getContractListFromES(Integer current, Integer size, String keywords) {
if (StringUtils.isEmpty(keywords)) {
return ApiResultUtil.fail(ApiExecStatus.INVALID_PARAM.getMsg());
}
AggregatedPage<ESContract> esContracts = contractESService.queryESContractPage(current, size, keywords);
IPage<ESContract> page = new Page<>();
page.setRecords(esContracts.getContent());
page.setTotal(esContracts.getTotalElements());
page.setPages(esContracts.getTotalPages());
return ApiResultUtil.success(page);
}
Model层:
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.io.Serializable;
/**
* <p>
* 合同基础信息表
* </p>
*
* @author Administrator
* @since 2020-04-09
*/
@Data
@Document(indexName = "ctscm", type = "doc", createIndex = false)
public class ESContract implements Serializable {
@Id
@Field(store = true, type = FieldType.Integer, index = false)
@JsonProperty("contract_id")
private Integer contractId;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("contract_code")
private String contractCode;
@Field(store = true, type = FieldType.Integer, index = false)
@JsonProperty("contract_type")
private String contractType;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("buyer_name")
private String buyerName;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("seller_name")
private String sellerName;
@Field(store = true, type = FieldType.Integer, index = false)
@JsonProperty("cus_id")
private Integer cusId;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("cus_name")
private String cusName;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("contract_total")
private String contractTotal;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("pay_mode")
private String payMode;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("start_date")
private String startDate;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("end_date")
private String endDate;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("sign_date")
private String signDate;
@Field(store = true, type = FieldType.Integer, index = false)
@JsonProperty("execution_status")
private String executionStatus;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("car_remark")
private String carRemark;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("contract_remark")
private String contractRemark;
@Field(store = true, type = FieldType.Text, index = false)
@JsonProperty("contract_attach")
private String contractAttach;
}
Service层:
import com.ihanchen.es.entity.ESContract;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
/**
* <p>
* 合同基础信息表 服务类
* </p>
*
* @author gaopeng
* @since 2020-09-09
*/
public interface IContractESService {
/**
* @param current 当前页
* @param size 每页数量
* @param keywords 关键词
* @return
*/
public AggregatedPage<ESContract> queryESContractPage(
Integer current,
Integer size,
String keywords);
}
Service实现层:
import com.ihanchen.es.entity.ESContract;
import com.ihanchen.es.service.IContractESService;
import org.apache.commons.lang3.ObjectUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author gaopeng
* @date:2020-09-09
*/
@Service
public class ContractESServiceImpl implements IContractESService {
@Autowired
private ElasticsearchTemplate esTemplate;
@Override
public AggregatedPage<ESContract> queryESContractPage(Integer current, Integer size, String keywords) {
if (ObjectUtils.isEmpty(current)) {
current = 1;
}
if (ObjectUtils.isEmpty(size)) {
size = 10;
}
Integer offset = (current - 1) * size;
Pageable pageable = PageRequest.of(offset, size);
SortBuilder sortBuilder = new FieldSortBuilder("contract_id").order(SortOrder.ASC);
SearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keywords, "contract_code", "contract_total", "execution_status", "cus_name"))
//.withHighlightFields(new HighlightBuilder.Field(field))
.withSort(sortBuilder)
.withPageable(pageable)
.build();
AggregatedPage<ESContract> pagedItems = esTemplate.queryForPage(query, ESContract.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<ESContract> contractHighLightList = new ArrayList<>();
SearchHits hits = response.getHits();
for (SearchHit h : hits) {
// HighlightField highlightField = h.getHighlightFields().get(field);
// String itemName = highlightField.getFragments()[0].toString();
Integer contractId = (Integer) h.getSourceAsMap().get("contract_id");
String contractCode = (String) h.getSourceAsMap().get("contract_code");
String contractType = (String) h.getSourceAsMap().get("contract_type");
String startDate = (String) h.getSourceAsMap().get("start_date");
String endDate = (String) h.getSourceAsMap().get("end_date");
String signDate = (String) h.getSourceAsMap().get("sign_date");
String executionStatus = (String) h.getSourceAsMap().get("execution_status");
String contractTotal = (String) h.getSourceAsMap().get("contract_total");
String cusName = (String) h.getSourceAsMap().get("cus_name");
ESContract esContract = new ESContract();
esContract.setContractId(contractId);
esContract.setContractCode(contractCode);
esContract.setContractType(contractType);
esContract.setCusName(cusName);
esContract.setStartDate(startDate);
esContract.setEndDate(endDate);
esContract.setSignDate(signDate);
esContract.setExecutionStatus(executionStatus);
esContract.setContractTotal(contractTotal);
contractHighLightList.add(esContract);
}
return new AggregatedPageImpl<>((List<T>) contractHighLightList,
pageable,
response.getHits().totalHits);
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
return null;
}
});
return pagedItems;
}
}