spring boot 整合 elasticsearch7.10.0(demo)
阿新 • • 發佈:2021-11-29
上一篇介紹了6.5.3的整合,這次是7.10.0整合,使用elasticsearch-rest-high-level-client,可以看下和使用spring-data的區別還是挺大
說明一下使用兩個版本主要是兩個專案不一樣,都是實際案例
1.開發環境:
springboot 2.2.8
elasticsearch 7.10.0 9200 9300 單機部署
2.pom檔案
<elasticsearch.version>7.10.1</elasticsearch.version> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticsearch.version}</version> </dependency>
3.bootstrap檔案
# elasticsearch配置檔案
elasticsearch:
rest:
uris: http://127.0.0.1:9200
read-timeout: 90
username:
password:
4.獲取properties配置
@Data @Component public class ElasticsearchProperties { privatestatic final String INDEXNAME = "demo"; @Value("${spring.elasticsearch.rest.uris}") private String uris; @Value("${spring.elasticsearch.rest.username}") private String username; @Value("${spring.elasticsearch.rest.password}") private String password; }
5.初始化bean
@Configuration @Slf4j public class ElasticSearchConfiguration { @Autowired private ElasticsearchProperties elasticsearchProperties; @Bean(destroyMethod = "close") @Scope("singleton") public RestHighLevelClient restHighLevelClient() { String username = elasticsearchProperties.getUsername(); String password = elasticsearchProperties.getPassword(); String scheme = elasticsearchProperties.getUris().split(":")[0]; String[] hosts = elasticsearchProperties.getUris().split("\\//")[1].split(":"); String hostName = hosts[0]; Integer port = Integer.parseInt(hosts[1]); HttpHost httpHosts = new HttpHost(hostName, port, scheme); RestClientBuilder restClientBuilder = RestClient.builder(httpHosts); //es賬號密碼(預設使用者名稱為elastic) if (StringUtils.isNoneBlank(username)) { final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> { httpClientBuilder.disableAuthCaching(); httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); return httpClientBuilder; }); } RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder); return restHighLevelClient; } }
6.索引操作
@Service @Slf4j public class ElasticsearchIndex { @Autowired private RestHighLevelClient restHighLevelClient; /** * 建立索引 * @param indexName * @return */ @SneakyThrows public boolean createIndex(String indexName) { boolean flag = existIndex(indexName); if (!flag) { CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName); restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); log.info("建立 {} 索引成功",indexName); flag = true; } else { log.info("{} 索引已經存在",indexName); } return flag; } /** * 檢查索引是否存在 */ @SneakyThrows public boolean existIndex(String indexName) { GetIndexRequest getIndexRequest = new GetIndexRequest(indexName); return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT); } /** * 刪除索引 * @param indexName */ @SneakyThrows public boolean deleteIndex(String indexName) { boolean flag = existIndex(indexName); if (flag) { DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName); AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT); log.info("刪除 {} 索引成功",indexName); return acknowledgedResponse.isAcknowledged(); } log.info("刪除 {} 索引失敗",indexName); return false; } }
7.文件操作及封裝物件
@Service @Slf4j public class ElasticsearchDocument { @Autowired private RestHighLevelClient restHighLevelClient; @Autowired private ElasticsearchIndex elasticsearchIndex; private static final String INDEXNAME = "demo"; @SneakyThrows public void insertDocument(EsData<AqZzFile> esData) { String indexName = INDEXNAME; AqZzFile aqZzFile = esData.getData(); elasticsearchIndex.createIndex(indexName); IndexRequest indexRequest = new IndexRequest(indexName); indexRequest.id(aqZzFile.getId()); indexRequest.source(JSON.toJSONString(aqZzFile),XContentType.JSON); IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT); log.info("索引{} 插入資料成功,id是 {}", indexName, aqZzFile.getId()); } @SneakyThrows public void updateDocument(EsData<AqZzFile> esData) { String indexName = INDEXNAME; AqZzFile aqZzFile = esData.getData(); boolean flag = existsById(indexName, aqZzFile.getId()); if (flag) { UpdateRequest updateRequest = new UpdateRequest(indexName,aqZzFile.getId()); updateRequest.doc(JSON.toJSONString(aqZzFile), XContentType.JSON); UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT); log.info("{} 索引中id為 {} 的文件修改成功!", indexName, aqZzFile.getId()); } } @SneakyThrows public void deleteDocument(String indexName,String id) { boolean flag = existsById(indexName, id); if (flag) { DeleteRequest deleteRequest = new DeleteRequest(indexName,id); DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT); log.info("{} 索引中id為 {} 的文件刪除成功!", indexName, id); } } @SneakyThrows public boolean existsById(String indexName,String id){ GetRequest request = new GetRequest(indexName, id); //不獲取返回的_source的上下文 request.fetchSourceContext(new FetchSourceContext(false)); request.storedFields("_none_"); boolean flag = restHighLevelClient.exists(request, RequestOptions.DEFAULT); log.info("{} 索引中 {} 的文件是否 {} 存在", indexName, id, flag); return flag; } @SneakyThrows public void searchDocument(EsData<AqZzFile> esData) { String indexName = INDEXNAME; AqZzFile aqZzFile = esData.getData(); SearchRequest searchRequest = new SearchRequest(indexName); //構建搜尋條件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field(""); searchSourceBuilder.highlighter(highlightBuilder); //執行查詢 searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); SearchHits hits = searchResponse.getHits(); } /** * 查詢並分頁 * @return */ @SneakyThrows public List<Map<String, Object>> searchListData(EsData<AqZzFile> esData) { String indexName = INDEXNAME; Integer from = esData.getFrom(); Integer size = esData.getSize(); String highlightField = "title"; String startTime = esData.getStartTime(); String endTime = esData.getEndTime(); String sortField = esData.getSortField(); AqZzFile aqZzFile = esData.getData(); SearchRequest searchRequest = new SearchRequest(indexName); //構建查詢條件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); if (Objects.nonNull(aqZzFile)) { //模糊匹配 if (StringUtils.isNoneBlank(aqZzFile.getTitle())) { searchSourceBuilder.query(QueryBuilders.matchQuery("title",aqZzFile.getTitle())); } //匹配(精準匹配) if (StringUtils.isNoneBlank(aqZzFile.getJzCode())) { searchSourceBuilder.query(QueryBuilders.termQuery("jzCode", aqZzFile.getJzCode())); } //匹配(精準匹配) if (StringUtils.isNoneBlank(aqZzFile.getJxCode())) { searchSourceBuilder.query(QueryBuilders.termQuery("jxCode", aqZzFile.getJxCode())); } } //時間範圍匹配 if (StringUtils.isNoneBlank(startTime) && StringUtils.isNoneBlank(endTime)) { searchSourceBuilder.query(QueryBuilders.rangeQuery("creatTime").from(DateTime.of(startTime,"yyyy-MM-dd hh:mm:ss")).to(DateTime.of(endTime,"yyyy-MM-dd hh:mm:ss"))); } //設定確定結果要從哪個索引開始搜尋的from選項,預設為0 from = from <= 1 ? 0 : (from -1) * size; searchSourceBuilder.from(from); searchSourceBuilder.size(size); if (StringUtils.isNotEmpty(sortField)) { //排序欄位,注意如果proposal_no是text型別會預設帶有keyword性質,需要拼接.keyword searchSourceBuilder.sort(sortField + ".keyword", SortOrder.ASC); } //高亮 if (StringUtils.isNoneBlank(highlightField)) { HighlightBuilder highlight = new HighlightBuilder(); highlight.field(highlightField); //關閉多個高亮 highlight.requireFieldMatch(false); highlight.preTags("<span style='color:red'>"); highlight.postTags("</span>"); searchSourceBuilder.highlighter(highlight); } //不返回源資料。只有條數之類的資料。 //builder.fetchSource(false); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); log.info("==" + searchResponse.getHits().getTotalHits()); if (searchResponse.status().getStatus() == 200) { // 解析物件 return setSearchResponse(searchResponse, highlightField); } return null; } /** * 高亮結果集 特殊處理 * map轉物件 JSONObject.parseObject(JSONObject.toJSONString(map), Content.class) * @param searchResponse * @param highlightField */ public 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); hit.getSourceAsMap().put("id", hit.getId()); //原來的結果 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; } }
@ApiModel(value = "es搜尋",description = "es搜尋") public class EsData<T> implements Serializable { private static final long serialVersionUID = 5626216451006492696L; @ApiModelProperty(value = "每頁條數") private Integer size = 10; @ApiModelProperty(value = "第幾頁開始") private Integer from = 0; @ApiModelProperty(value = "排序欄位") private String sortField; @ApiModelProperty(value = "開始時間") private String startTime; @ApiModelProperty(value = "結束時間") private String endTime; private T data; }
8.controller
@RequestMapping(value = "/xxx/file") public class AqZzFileController { @Autowired private AqZzFileService aqZzFileService; @PostMapping("/getPageData") @ApiOperation(value = "自主學習-列表(分頁)查詢") public ResponseData getPageData(@RequestBody CommentParam<AqZzFile> commentParam) { log.info("自主學習查詢入參為: {} ", JSON.toJSONString(commentParam)); Page page = commentParam.getPage(); AqZzFile aqZzFile = commentParam.getData(); IPage<List<AqZzFile>> pageList = aqZzFileService.getAllPageData(aqZzFile, page); log.info("自主學習分頁查詢獲取的資料為: {}", JSON.toJSONString(pageList)); if (Objects.nonNull(pageList)) { return ResponseData.ok(pageList); } return ResponseData.failed(ConstantCode.DATA_EMPTY); } @PostMapping @ApiOperation(value = "新增") public ResponseData save(@RequestBody AqZzFile aqZzFile){ log.info("檔案管理新增入參為: {} ", JSON.toJSONString(aqZzFile)); try { aqZzFileService.saveOrUpdateEntity(aqZzFile); return ResponseData.ok(null); } catch (Exception e) { e.printStackTrace(); } return ResponseData.failed(ConstantCode.SERVER_ERROR); } @ApiOperation(value = "自主學習-按id查詢資料") @GetMapping("/getDataById/{id}") public ResponseData getDataById(@PathVariable("id") String id){ log.info("資料字典按ID查詢資料入參為: {} ", id); AqZzFile aqZzFile = aqZzFileService.getById(id); if (Objects.nonNull(aqZzFile)) { return ResponseData.ok(aqZzFile); } return ResponseData.failed(ConstantCode.DATA_EMPTY); } @PutMapping("/{id}") @ApiOperation(value = "修改") public ResponseData update(@PathVariable(name = "id") String id, @RequestBody AqZzFile aqZzFile) { log.info("檔案管理管理修改入參為: {}, {} ", id, JSON.toJSONString(aqZzFile)); try { aqZzFile.setId(id); aqZzFileService.saveOrUpdateEntity(aqZzFile); return ResponseData.ok(null); } catch (Exception e) { e.printStackTrace(); } return ResponseData.failed(ConstantCode.SERVER_ERROR); } @DeleteMapping("/{id}") @ApiOperation(value = "按ID刪除") public ResponseData remove(@PathVariable(name = "id") String id){ log.info("檔案管理按ID刪除入參為: {} ",id); try { aqZzFileService.deleteEntity(id); return ResponseData.ok(null); } catch (Exception e) { e.printStackTrace(); } return ResponseData.failed(ConstantCode.SERVER_ERROR); } @PostMapping("/getPageData/search") @ApiOperation(value = "自主學習-搜尋引擎搜尋") public ResponseData search(@RequestBody EsData<AqZzFile> esData) { log.info("自主學習搜尋引擎查詢入參為: {} ", JSON.toJSONString(esData)); List<Map<String, Object>> pageList = aqZzFileService.search(esData); log.info("自主學習搜尋引擎查詢獲取的資料為: {}", JSON.toJSONString(pageList)); if (Objects.nonNull(pageList)) { return ResponseData.ok(pageList); } return ResponseData.failed(ConstantCode.DATA_EMPTY); } }
已經測試通過
本文來自部落格園,作者:小輝輝。。,轉載請註明原文連結:https://www.cnblogs.com/zjylsh/p/15618070.html