JAVA从ES分页查询数据
从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; } }