1. 程式人生 > 其它 >spring boot 整合 elasticsearch7.10.0(demo)

spring boot 整合 elasticsearch7.10.0(demo)

上一篇介紹了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 {
    private
static 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