SpringBoot 2.x集成Elasticsearch
环境配置:SpringBoot:2.6.0 ,Elasticsearch:7.16.2
1、pom配置
<properties> <elasticsearch.version>7.16.2</elasticsearch.version> </properties> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>${elasticsearch.version}</version> </dependency> <!-- ES 版本 --> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-elasticsearch</artifactId> <version>4.1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.elasticsearch.plugin/transport-netty4-client --> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>${elasticsearch.version}</version> </dependency>
2、yaml配置
#elasticsearch 多个地址逗号隔开 elasticsearch: hostlist: ${eshostlist:10.1.13.235:9200} ips: 10.1.13.235 port: 9300 pool: 30 cluster: elasticsearch
3、配置config,获取springBean工具类见下文SpringContextUtils
import com.test.util.SpringContextUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpHost; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.bulk.*; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.core.TimeValue; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Iterator; import java.util.function.BiConsumer; /** * @Author bug * @create 2022/05/6 19:43 * @Description */ @Configuration @Slf4j public class ESConfig { @Value("${elasticsearch.hostlist}") private String hostlist; /** * Description: 高版本客户端 * * @Author: bug * @Date: 2022/05/15 10:20 * @Return: org.elasticsearch.client.RestHighLevelClient * @throws: */ @Bean("restHighLevelClient") public RestHighLevelClient restHighLevelClient() { RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder(); // 解析 hostlist 配置信息。假如以后有多个,则需要用 , 分开 String[] split = hostlist.split(","); // 创建 HttpHost 数组,其中存放es主机和端口的配置信息 HttpHost[] httpHostArray = new HttpHost[split.length]; for (int i = 0; i < split.length; i++) { String item = split[i]; httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http"); } // 创建RestHighLevelClient客户端 return new RestHighLevelClient(RestClient.builder(httpHostArray)); } /** * Description: 项目主要使用 RestHighLevelClient,对于低级的客户端暂时不用 * * @Author: bug * @Date: 2022/05/15 10:20 * @Return: org.elasticsearch.client.RestClient * @throws: */ @Bean public RestClient restClient() { // 解析hostlist配置信息 String[] split = hostlist.split(","); // 创建HttpHost数组,其中存放es主机和端口的配置信息 HttpHost[] httpHostArray = new HttpHost[split.length]; for (int i = 0; i < split.length; i++) { String item = split[i]; httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http"); } return RestClient.builder(httpHostArray).build(); } public static RestHighLevelClient getRestHighLevelClient() { RestHighLevelClient restHighLevelClient = null; try { restHighLevelClient = (RestHighLevelClient) SpringContextUtils.getBeanListOfType(RestHighLevelClient.class).get(0); } catch (Exception e) { log.error("获取restHighLevelClient失败:" + e.toString()); } return restHighLevelClient; } /** * Description: 封装 bulkProcessor * * @Author: bug * @Date: 2022/05/15 10:19 * @Return: org.elasticsearch.action.bulk.BulkProcessor * @throws: */ @Bean(name = "bulkProcessor") public BulkProcessor bulkProcessor() { BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer = (request, bulkListener) -> getRestHighLevelClient().bulkAsync(request, RequestOptions.DEFAULT, bulkListener); return BulkProcessor.builder(bulkConsumer, new BulkProcessor.Listener() { @Override public void beforeBulk(long executionId, BulkRequest request) { // todo do something int i = request.numberOfActions(); log.info("ES 同步数量 Executing bulk [{}] with {} requests", executionId, i); } @Override public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { if (response.hasFailures()) { log.error("Bulk [{}] executed with failures", executionId); } else { log.info("Bulk [{}] completed in {} milliseconds", executionId, response.getTook().getMillis()); } // todo do something Iterator<BulkItemResponse> iterator = response.iterator(); while (iterator.hasNext()) { log.info("afterBulk--->>>" + JSON.toJSONString(iterator.next())); } } @Override public void afterBulk(long executionId, BulkRequest request, Throwable failure) { // todo do something log.error("ES 同步失败 Failed to execute bulk", failure); } //达到刷新的条数,达到刷新的大小,固定刷新的时间频率,并发线程数,重试补偿策略 }).setBulkActions(1000) .setBulkSize(new ByteSizeValue(1, ByteSizeUnit.MB)) .setFlushInterval(TimeValue.timeValueMinutes(5)) .setConcurrentRequests(2) .setBackoffPolicy(BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3)) .build(); } }
4、工具类SpringContextUtils.java
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @Author bug * @create 2022/05/6 16:12 * @Description 获取srpingBean */ @Component public class SpringContextUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtils.applicationContext = applicationContext; } public static <T> List<T> getBeanListOfType(Class<T> clazz) { List<T> result = new ArrayList<>(); Map<String, T> map = applicationContext.getBeansOfType(clazz); if (null != map) { result.addAll(map.values()); } return result; } public static <T> List<T> getBeanListOfName(String className) throws Exception { Class clazz = Class.forName(className); return getBeanListOfType(clazz); } public static void autowireBean(Object bean) { applicationContext.getAutowireCapableBeanFactory().autowireBean(bean); } public static <T> T getBean(String name,Class<T> clazz){ return applicationContext.getBean(name, clazz); } }
5、工具类ElasticsearchUtil.java
import com.test.model.domain.EsPage; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.bulk.BulkProcessor; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.Strings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.query.*; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.xcontent.XContentType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import java.io.IOException; import java.util.ArrayList; import java.util.Map; import java.util.List; import java.util.UUID; /** * @Author bug * @create 2022/05/7 13:45 * @Description ES工具类 该工具类适用于7.*已上版本 * 最好不要自定义id 会影响插入速度 */ @Component @Slf4j public class ElasticsearchUtil { @Autowired @Qualifier("restHighLevelClient") private RestHighLevelClient restHighLevelClient; @Autowired @Qualifier("bulkProcessor") private BulkProcessor bulkProcessor; /** * 关键字 .keyword */ public static final String KEYWORD = ".keyword"; /** * 关键字 * */ public static final String WILD_CODE_A = "*"; /** * 关键字 ? */ public static final String WILD_CODE_B = "?"; /** * 创建索引 * * @param index * @return */ public boolean createIndex(String index) throws IOException { if (isIndexExist(index)) { log.error("Index is exits!"); return false; } //1.创建索引请求 CreateIndexRequest request = new CreateIndexRequest(index); //2.执行客户端请求 org.elasticsearch.client.indices.CreateIndexResponse response = restHighLevelClient.indices() .create(request, RequestOptions.DEFAULT); return response.isAcknowledged(); } /** * 判断索引是否存在 * * @param index * @return */ public boolean isIndexExist(String index) throws IOException { GetIndexRequest request = new GetIndexRequest(index); boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT); return exists; } /** * 删除索引 * * @param index * @return */ public boolean deleteIndex(String index) throws IOException { if (!isIndexExist(index)) { log.error("Index is not exits!"); return false; } DeleteIndexRequest request = new DeleteIndexRequest(index); AcknowledgedResponse delete = restHighLevelClient.indices() .delete(request, RequestOptions.DEFAULT); return delete.isAcknowledged(); } /** * 数据添加,自定义id * * @param object 要增加的数据 * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID,为null时es随机生成 * @return */ public String addData(Object object, String index, String type, String id) throws Exception { //创建请求 IndexRequest request = new IndexRequest(index, type); //规则 put /test_index/_doc/1 request.id(id); //将数据放入请求 json IndexRequest source = request.source(JacksonMapperUtils.obj2json(object), XContentType.JSON); //客户端发送请求 IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT); return response.getId(); } /** * 数据添加 随机id 可能存在性能问题 * * @param object 要增加的数据 * @param index 索引,类似数据库 * @param type 类似数据表 * @return */ public String addData(Object object, String index, String type) throws Exception { return addData(object, index, type, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase()); } /** * 通过ID删除数据 * * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID * @return */ public void deleteDataById(String index, String type, String id) throws IOException { DeleteRequest request = new DeleteRequest(index, type, id); restHighLevelClient.delete(request, RequestOptions.DEFAULT); } /** * 通过ID 更新数据 * * @param object 要更新数据 * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID * @return */ public void updateDataById(Object object, String index, String type, String id) throws Exception { log.info("es更新--->>>esId:" + id); UpdateRequest update = new UpdateRequest(index, type, id); update.doc(JacksonMapperUtils.obj2json(object), XContentType.JSON); restHighLevelClient.update(update, RequestOptions.DEFAULT); log.info("es更新返回--->>>esId:" + id); } /** * 通过ID 更新数据 * * @param object 要更新数据 * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID * @return */ public void updateDocById(Map<String, Object> object, String index, String type, String id) throws Exception { log.info("es更新--->>>esId:" + id); UpdateRequest update = new UpdateRequest(index, type, id).doc(object); update.doc(JacksonMapperUtils.obj2json(object), XContentType.JSON); restHighLevelClient.update(update, RequestOptions.DEFAULT); log.info("es更新返回--->>>esId:" + id); } /** * Description: 批量更新 * * @param: list * @param: index * @param: type * @param: keyId * @Author: 123107 * @Date: 2022/05/15 10:34 * @Return: void * @throws: */ public void bulkUpdate(List<?> list, String index, String type, String keyId) throws Exception { log.info("es bulk 更新--->>>start"); for(Object object : list){ String json = JacksonMapperUtils.obj2json(object); Map<String, Object> map = JacksonMapperUtils.json2map(JacksonMapperUtils.obj2json(object)); String id = String.valueOf(map.get(keyId)); UpdateRequest update = new UpdateRequest(index, id).doc(json, XContentType.JSON); update.doc(json, XContentType.JSON); bulkProcessor.add(update); } log.info("es bulk 更新--->>end"); } /** * 通过ID获取数据 * * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) * @return */ public Map<String, Object> searchDataById(String index, String type, String id, String fields) throws IOException { GetRequest request = new GetRequest(index, type, id); if (StringUtils.isNotEmpty(fields)) { //只查询特定字段。如果需要查询所有字段则不设置该项。 request.fetchSourceContext(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY)); } GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT); return response.getSource(); } /** * 通过ID判断文档是否存在 * * @param index 索引,类似数据库 * @param type 类似数据表 * @param id 数据ID * @return */ public boolean existsById(String index, String type, String id) throws IOException { GetRequest request = new GetRequest(index, type, id); //不获取返回的_source的上下文 request.fetchSourceContext(new FetchSourceContext(false)); request.storedFields("_none_"); return restHighLevelClient.exists(request, RequestOptions.DEFAULT); } /** * 批量插入false成功 * * @param index 索引,类似数据库 * @param type 类似数据表 * @param objects 数据 * @return */ public boolean bulkPost(String index, String type, List<?> objects) throws Exception{ BulkRequest bulkRequest = new BulkRequest(); BulkResponse response = null; //最大数量不得超过20万 for (Object object : objects) { IndexRequest request = new IndexRequest(index, type); request.source(JacksonMapperUtils.obj2json(object), XContentType.JSON); bulkRequest.add(request); } try { response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } return response.hasFailures(); } /** * 根据经纬度查询范围查找location 经纬度字段,distance 距离中心范围KM,lat lon 圆心经纬度 * * @param index * @param longitude * @param latitude * @param distance * @return */ public SearchResponse geoDistanceQuery(String index, Float longitude, Float latitude, String distance) throws IOException { if (longitude == null || latitude == null) { return null; } //拼接条件 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //QueryBuilder isdeleteBuilder = QueryBuilders.termQuery("isdelete", false); // 以某点为中心,搜索指定范围 GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("location"); distanceQueryBuilder.point(latitude, longitude); //查询单位:km distanceQueryBuilder.distance(distance, DistanceUnit.KILOMETERS); boolQueryBuilder.filter(distanceQueryBuilder); //boolQueryBuilder.must(isdeleteBuilder); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(boolQueryBuilder); SearchRequest searchRequest = new SearchRequest(index); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); return searchResponse; } /** * 获取低水平客户端 * * @return */ public RestClient getLowLevelClient() { return restHighLevelClient.getLowLevelClient(); } /** * 高亮结果集 特殊处理 * map转对象 JSONObject.parseObject(JSONObject.toJSONString(map), Content.class) * * @param searchResponse * @param highlightField */ private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) { //解析结果 ArrayList<Map<String, Object>> list = new ArrayList<>(); for (SearchHit hit : searchResponse.getHits().getHits()) { Map<String, HighlightField> high = hit.getHighlightFields(); HighlightField title = high.get(highlightField); Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果 //解析高亮字段,将原来的字段换为高亮字段 if (title != null) { Text[] texts = title.fragments(); String nTitle = ""; for (Text text : texts) { nTitle += text; } //替换 sourceAsMap.put(highlightField, nTitle); } list.add(sourceAsMap); } return list; } /** * 查询并分页 * 单个匹配termQuery * //不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词. * QueryBuilder queryBuilder=QueryBuilders.termQuery("fieldName", "fieldlValue"); * //分词查询,采用默认的分词器 * QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("fieldName", "fieldlValue"); * 多个匹配 * //不分词查询,参数1: 字段名,参数2:多个字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词. * QueryBuilder queryBuilder=QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2..."); * //分词查询,采用默认的分词器 * QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3"); * //匹配所有文件,相当于就没有设置查询条件 * QueryBuilder queryBuilder=QueryBuilders.matchAllQuery(); * <p> * 模糊查询常见的5个方法如下 * //1.常用的字符串查询-左右模糊 * QueryBuilders.queryStringQuery("fieldValue").field("fieldName"); * //2.常用的用于推荐相似内容的查询-如果不指定filedName,则默认全部,常用在相似内容的推荐上 * QueryBuilders.moreLikeThisQuery(new String[] {"fieldName"}).addLikeText("pipeidhua"); * //3.前缀查询 如果字段没分词,就匹配整个字段前缀 * QueryBuilders.prefixQuery("fieldName","fieldValue"); * //4.fuzzy query:分词模糊查询,通过增加fuzziness模糊属性来查询,如能够匹配hotelName为tel前或后加一个字母的文档,fuzziness 的含义是检索的term 前后增加或减少n个单词的匹配查询 * QueryBuilders.fuzzyQuery("hotelName", "tel").fuzziness(Fuzziness.ONE); * //5.wildcard query:通配符查询,支持* 任意字符串;?任意一个字符 * //前面是fieldname,后面是带匹配字符的字符串 * QueryBuilders.wildcardQuery("fieldName","ctr*"); * QueryBuilders.wildcardQuery("fieldName","c?r?"); * <p> * 范围查询 * //闭区间查询 * QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2"); * //开区间查询 默认是true,也就是包含 * QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2").includeUpper(false).includeLower(false); * //大于 * QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("fieldName").gt("fieldValue"); * //大于等于 * QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("fieldName").gte("fieldValue"); * //小于 * QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("fieldName").lt("fieldValue"); * //小于等于 * QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("fieldName").lte("fieldValue"); * <p> * 合查询/多条件查询/布尔查询 * QueryBuilders.boolQuery() * //文档必须完全匹配条件,相当于and * QueryBuilders.boolQuery().must(); * //文档必须不匹配条件,相当于not * QueryBuilders.boolQuery().mustNot(); * //至少满足一个条件,这个文档就符合should,相当于or * QueryBuilders.boolQuery().should(); * * @param index 索引名称 * @param type 类似数据表 * @param query 查询条件 * @param size 文档大小限制 * @param startPage 第几页开始 默认0开始 * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) * @param sortField 排序字段 * @param highlightField 高亮字段 * @return */ public EsPage searchListData(String index, String type, SearchSourceBuilder query, Integer size, Integer startPage, String fields, String sortField, String highlightField) throws IOException { SearchRequest request = new SearchRequest(index); //request.types(type); SearchSourceBuilder builder = query; if (StringUtils.isNotEmpty(fields)) { //只查询特定字段。如果需要查询所有字段则不设置该项。 builder.fetchSource(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY)); } startPage = startPage <= 0 ? 0 : startPage * size; //设置确定结果要从哪个索引开始搜索的from选项,默认为0 builder.from(startPage); builder.size(size); if (StringUtils.isNotEmpty(sortField)) { //排序字段,注意如果proposal_no是text类型会默认带有keyword性质,需要拼接.keyword builder.sort(sortField + ".keyword", SortOrder.ASC); } //高亮 if (StringUtils.isNotEmpty(highlightField)) { HighlightBuilder highlight = new HighlightBuilder(); highlight.field(highlightField); //关闭多个高亮 highlight.requireFieldMatch(false); highlight.preTags("<span style='color:red'>"); highlight.postTags("</span>"); builder.highlighter(highlight); } //不返回源数据。只有条数之类的数据。 //builder.fetchSource(false); request.source(builder); SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT); long totalHits = response.getHits().getTotalHits().value; log.info("totalHits==" + response.getHits().getTotalHits()); if (response.status().getStatus() == 200) { // 解析对象 List<Map<String, Object>> sourceList = setSearchResponse(response, highlightField); return new EsPage(startPage, size, (int) totalHits, sourceList); } return null; } /** * Description: 组装模糊查询参数 * * @param: filds 模糊查询列 * @param: querys 模糊查询内容 * @param: mustFilds 必须匹配列 * @param: mustQuerys 必须匹配内容 * @Author: 123107 * @Date: 2022/05/14 15:25 * @Return: org.elasticsearch.index.query.BoolQueryBuilder * @throws: */ public BoolQueryBuilder boolQueryBuilder(String filds, String querys, String mustFilds, String mustQuerys) { if (StringUtils.isBlank(filds) || StringUtils.isBlank(querys)) { return null; } String[] fildList = filds.split(","); String[] queryList = querys.split(","); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); for (String fild : fildList) { for (String query : queryList) { WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(fild + KEYWORD, WILD_CODE_A + query + WILD_CODE_A); boolQueryBuilder.should(wildcardQueryBuilder); } } boolQueryBuilder.minimumShouldMatch(1); //必须匹配条件 if (StringUtils.isNotBlank(mustFilds) && StringUtils.isNotBlank(mustQuerys)) { String[] mfilds = mustFilds.split(","); String[] mquserys = mustQuerys.split(","); if (mfilds.length == mquserys.length) { for (int i = 0; i < mfilds.length; i++) { QueryBuilder queryBuilder = QueryBuilders.termQuery(mfilds[i], mquserys[i]); boolQueryBuilder.must(queryBuilder); } } } return boolQueryBuilder; } }
6、EsPage类
import java.util.Map; import java.util.List; /** * @Author bug * @create 2022/05/7 9:31 * @Description */ public class EsPage { /** * 当前页 */ private int currentPage; /** * 每页显示多少条 */ private int pageSize; /** * 总记录数 */ private int recordCount; /** * 本页的数据列表 */ private List<Map<String, Object>> recordList; /** * 总页数 */ private int pageCount; /** * 页码列表的开始索引(包含) */ private int beginPageIndex; /** * 页码列表的结束索引(包含) */ private int endPageIndex; /** * 只接受前4个必要的属性,会自动的计算出其他3个属性的值 * * @param currentPage * @param pageSize * @param recordCount * @param recordList */ public EsPage(int currentPage, int pageSize, int recordCount, List<Map<String, Object>> recordList) { this.currentPage = currentPage; this.pageSize = pageSize; this.recordCount = recordCount; this.recordList = recordList; // 计算总页码 pageCount = (recordCount + pageSize - 1) / pageSize; // 计算 beginPageIndex 和 endPageIndex // >> 总页数不多于10页,则全部显示 if (pageCount <= 10) { beginPageIndex = 1; endPageIndex = pageCount; } // >> 总页数多于10页,则显示当前页附近的共10个页码 else { // 当前页附近的共10个页码(前4个 + 当前页 + 后5个) beginPageIndex = currentPage - 4; endPageIndex = currentPage + 5; // 当前面的页码不足4个时,则显示前10个页码 if (beginPageIndex < 1) { beginPageIndex = 1; endPageIndex = 10; } // 当后面的页码不足5个时,则显示后10个页码 if (endPageIndex > pageCount) { endPageIndex = pageCount; beginPageIndex = pageCount - 10 + 1; } } } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getRecordCount() { return recordCount; } public void setRecordCount(int recordCount) { this.recordCount = recordCount; } public List<Map<String, Object>> getRecordList() { return recordList; } public void setRecordList(List<Map<String, Object>> recordList) { this.recordList = recordList; } public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } public int getBeginPageIndex() { return beginPageIndex; } public void setBeginPageIndex(int beginPageIndex) { this.beginPageIndex = beginPageIndex; } public int getEndPageIndex() { return endPageIndex; } public void setEndPageIndex(int endPageIndex) { this.endPageIndex = endPageIndex; } }
7、使用示例
/** * Description: es 保存数据 //ES_INDEX 索引名称//ES_TYPE type * @param: obj 数据对象 * @param: id ES_id UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() * @Author: bug * @Date: 2022/05/7 18:48 * @Return: java.lang.String * @throws: */ public String insertEs(Object obj, String id) throws Exception { try { boolean exists = elasticsearchUtil.isIndexExist(EsIndexConstant.ES_INDEX); log.info(EsIndexConstant.ES_INDEX + ":index--->>>" + exists); if (!exists) { boolean create = elasticsearchUtil.createIndex(EsIndexConstant.ES_INDEX); log.info(EsIndexConstant.ES_INDEX + ":create--->>>" + create); } elasticsearchUtil.addData(obj, EsIndexConstant.ES_INDEX, EsIndexConstant.ES_TYPE, id); log.info(EsIndexConstant.ES_INDEX + ":es保存返回id--->>>" + id); return id; } catch (Exception e) { log.error("es保存异常:" + e.toString()); throw e; } } /** * Description: es 更新数据 //ES_INDEX 索引名称//ES_TYPE type * @param: obj 数据对象 * @param: esNumber ES_id * @Author: bug * @Date: 2022/05/7 18:48 * @Return: java.lang.String * @throws: */ public void updateEs(Object obj, String esNumber) throws Exception { try { boolean exists = elasticsearchUtil.isIndexExist(EsIndexConstant.ES_INDEX); log.info(EsIndexConstant.ES_INDEX + ":index--->>>" + exists); if (!exists) { boolean create = elasticsearchUtil.createIndex(EsIndexConstant.ES_INDEX); log.info(EsIndexConstant.ES_INDEX + ":create--->>>" + create); } elasticsearchUtil.updateDataById(obj, EsIndexConstant.ES_INDEX, EsIndexConstant.ES_TYPE, esNumber); log.info(EsIndexConstant.ES_INDEX + ":es编辑返回id--->>>" + esNumber); } catch (Exception e) { log.error("es更新异常:" + e.toString()); throw e; } } /** * Description: es 查询数据 从指定的txt字段中,查询含有words内容的数据//ES_INDEX 索引名称//ES_TYPE type * @param: words 要查询的内容 * @param: esNumber ES_id * @Author: bug * @Date: 2022/05/7 18:48 * @Return: java.lang.List * @throws: */ public List<Map<String, Object>> searchDataFromField(String words) int currentPage=0; int pageSize=10000; SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); BoolQueryBuilder boolQueryBuilder = elasticsearchUtil.boolQueryBuilder("txt", words, null, null); //增加筛选条件 userType ==1 //BoolQueryBuilder boolQueryBuilder = elasticsearchUtil.boolQueryBuilder("txt", words, "userType","1"); searchSourceBuilder.query(boolQueryBuilder); EsPage esPage = null; //要返回的数据字段 String fields = "esId,systemId,systemName,fileName,createTime"; try { esPage = elasticsearchUtil.searchListData(EsIndexConstant.ES_INDEX, EsIndexConstant.ES_TYPE searchSourceBuilder, pageSize, currentPage, fields, null, null); } catch (IOException e) { e.printStackTrace(); } List<Map<String, Object>> records = esPage.getRecordList(); return records; }