1. 程式人生 > 其它 >SpringBoot整合Elasticsearch(官方client)

SpringBoot整合Elasticsearch(官方client)

技術標籤:ElasticSearchelasticsearchspringbootrestClient

本文主要講述了 Spring Boot 如何整合 ElasticSearch 搜尋引擎,
並使用 ElasticSearch 官方推薦的 Java High Level REST Client Java 客戶端操作

文末附原始碼地址

1.開發環境

  • java 8
  • springboot版本:2.3.0.RELEASE
  • elasticSearch版本: 7.4.0
  • elasticsearch-rest-client :7.4.0
  • elasticsearch-rest-high-level-client:7.4.0

2.pom依賴

<!--elasticsearch-->
<dependency>
  <groupId>org.elasticsearch</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>7.4.0</version>
</dependency>
<!-- Java Low Level REST Client -->
<dependency>
  <groupId>org.elasticsearch.client</
groupId
>
<artifactId>elasticsearch-rest-client</artifactId> <version>7.4.0</version> </dependency> <!-- Java High Level REST Client --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</
artifactId
>
<version>7.4.0</version> </dependency>

3.配置application.properties

server.port=8083

logging.level.root=INFO
logging.level.com.example=DEBUG

# elasticSearch 配置
# 連線多個逗號分隔,格式(IP:埠)
config.elasticsearch.address=192.168.3.21:9201,192.168.3.22:9201,192.168.3.23:9201
#未加驗證可以不配置賬戶
#config.elasticsearch.userName=elastic
#config.elasticsearch.password=1234567
config.elasticsearch.connectTimeout=10000
config.elasticsearch.socketTimeout=60000
config.elasticsearch.connectionRequestTimeout=15000

4.配置屬性

/**
 * ElasticSearch配置
 *
 * @author 程式設計師小強
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "config.elasticsearch")
public class ElasticSearchProperty {

    /**
     * 連線地址,格式:IP:埠
     * 多個逗號分隔
     * 示例:127.0.0.1:9201,127.0.0.1:9202,127.0.0.1:9203
     */
    private String address;

    /**
     * 使用者名稱
     */
    private String userName;

    /**
     * 密碼
     */
    private String password;

    /**
     * 連線超時時間
     * 預設10s
     */
    private int connectTimeout = 10000;

    /**
     * socket超時時間
     * 預設10s
     */
    private int socketTimeout = 10000;

    /**
     * 請求連線超時時間
     * 預設10s
     */
    private int connectionRequestTimeout = 10000;

}

5.客戶端連線配置

/**
 * ElasticSearch Rest client 配置
 *
 * @author 程式設計師小強
 */
@Configuration
public class ElasticSearchConfig {
    private static final Logger log = LoggerFactory.getLogger(ElasticSearchConfig.class);

    @Resource
    private ElasticSearchProperty elasticSearchProperty;

    @Bean
    public RestClientBuilder restClientBuilder() {
        Assert.notNull(elasticSearchProperty, "elasticSearchProperty cannot null ");
        Assert.notNull(elasticSearchProperty.getAddress(), "address hosts  cannot null ");

        //ElasticSearch 連線地址地址
        HttpHost[] httpHosts = this.getElasticSearchHttpHosts();

        return RestClient.builder(httpHosts).setRequestConfigCallback(requestConfigBuilder -> {
            //設定連線超時時間
            requestConfigBuilder.setConnectTimeout(elasticSearchProperty.getConnectTimeout());
            requestConfigBuilder.setSocketTimeout(elasticSearchProperty.getSocketTimeout());
            requestConfigBuilder.setConnectionRequestTimeout(elasticSearchProperty.getConnectionRequestTimeout());
            return requestConfigBuilder;
        }).setFailureListener(new RestClient.FailureListener() {
            //某節點失敗,這裡可以做一些告警
            @Override
            public void onFailure(Node node) {
                log.error("[ ElasticSearchClient ] >>  node :{}, host:{},  fail ", node.getName(), node.getHost());
            }
        }).setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.disableAuthCaching();
            //設定賬密
            return getHttpAsyncClientBuilder(httpClientBuilder);
        });
    }
    
    /**
     * ElasticSearch Rest client 配置
     *
     * @return RestHighLevelClient
     */
    @Bean
    public RestHighLevelClient restHighLevelClient(@Qualifier("restClientBuilder") RestClientBuilder restClientBuilder) {
        return new RestHighLevelClient(restClientBuilder);
    }

    /**
     * ElasticSearch 連線地址
     * 多個逗號分隔
     * 示例:127.0.0.1:9201,127.0.0.1:9202,127.0.0.1:9203
     */
    private HttpHost[] getElasticSearchHttpHosts() {
        String[] hosts = elasticSearchProperty.getAddress().split(",");
        HttpHost[] httpHosts = new HttpHost[hosts.length];
        for (int i = 0; i < httpHosts.length; i++) {
            String host = hosts[i];
            host = host.replaceAll("http://", "").replaceAll("https://", "");
            Assert.isTrue(host.contains(":"), String.format("your host %s format error , Please refer to [ 127.0.0.1:9200 ] ", host));
            httpHosts[i] = new HttpHost(host.split(":")[0], Integer.parseInt(host.split(":")[1]), "http");
        }
        return httpHosts;
    }

    private HttpAsyncClientBuilder getHttpAsyncClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {
        if (StringUtils.isEmpty(elasticSearchProperty.getUserName()) || StringUtils.isEmpty(elasticSearchProperty.getPassword())) {
            return httpClientBuilder;
        }
        //賬密設定
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        //es賬號密碼(一般使用,使用者elastic)
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticSearchProperty.getUserName(), elasticSearchProperty.getPassword()));
        httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        return httpClientBuilder;
    }
}

6.官方客戶端封裝元件

/**
 * ElasticSearch 客戶端 RestHighLevelClient Api介面封裝
 * <p>
 * 官方Api地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high.html
 *
 * @author 程式設計師小強
 * @date 2020-12-06 22:46
 */
@Slf4j
@Component
public class ElasticSearchRestApiClient {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 預設主分片數
     */
    private static final int DEFAULT_SHARDS = 3;
    /**
     * 預設副本分片數
     */
    private static final int DEFAULT_REPLICAS = 2;

    /**
     * 判斷索引是否存在
     *
     * @param index 索引
     * @return 返回 true,表示存在
     */
    public boolean existsIndex(String index) {
        try {
            GetIndexRequest request = new GetIndexRequest(index);
            request.local(false);
            request.humanReadable(true);
            request.includeDefaults(false);

            return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> get index exists exception ,index:{} ", index, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> get index exists exception {}", e);
        }
    }

    /**
     * 建立 ES 索引
     *
     * @param index      索引
     * @param properties 文件屬性集合
     * @return 返回 true,表示建立成功
     */
    public boolean createIndex(String index, Map<String, Object> properties) {
        try {
            XContentBuilder builder = XContentFactory.jsonBuilder();
            // 注:ES 7.x 後的版本中,已經棄用 type
            builder.startObject()
                    .startObject("mappings")
                    .field("properties", properties)
                    .endObject()
                    .startObject("settings")
                    //分片數
                    .field("number_of_shards", DEFAULT_SHARDS)
                    //副本數
                    .field("number_of_replicas", DEFAULT_REPLICAS)
                    .endObject()
                    .endObject();
            CreateIndexRequest request = new CreateIndexRequest(index).source(builder);
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> createIndex exception ,index:{},properties:{}", index, properties, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> createIndex exception ");
        }
    }

    /**
     * 刪除索引
     *
     * @param index 索引
     * @return 返回 true,表示刪除成功
     */
    public boolean deleteIndex(String index) {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(index);
            AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);

            return response.isAcknowledged();
        } catch (ElasticsearchException e) {
            //索引不存在-無需刪除
            if (e.status() == RestStatus.NOT_FOUND) {
                log.error("[ elasticsearch ] >>  deleteIndex >>  index:{}, Not found ", index, e);
                return false;
            }
            log.error("[ elasticsearch ] >> deleteIndex exception ,index:{}", index, e);
            throw new ElasticSearchRunException("elasticsearch deleteIndex exception ");
        } catch (IOException e) {
            //其它未知異常
            log.error("[ elasticsearch ] >> deleteIndex exception ,index:{}", index, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >>  deleteIndex exception {}", e);
        }
    }

    /**
     * 獲取索引配置
     *
     * @param index 索引
     * @return 返回索引配置內容
     */
    public GetSettingsResponse getIndexSetting(String index) {
        try {
            GetSettingsRequest request = new GetSettingsRequest().indices(index);
            return restHighLevelClient.indices().getSettings(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            //其它未知異常
            log.error("[ elasticsearch ] >> getIndexSetting exception ,index:{}", index, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >>  getIndexSetting exception {}", e);
        }
    }


    /**
     * 判斷文件是否存在
     *
     * @param index 索引
     * @return 返回 true,表示存在
     */
    public boolean existsDocument(String index, String id) {
        try {
            GetRequest request = new GetRequest(index, id);
            //禁用獲取_source
            request.fetchSourceContext(new FetchSourceContext(false));
            //禁用獲取儲存的欄位。
            request.storedFields("_none_");

            return restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> get document exists exception ,index:{} ", index, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> get document  exists exception {}", e);
        }
    }

    /**
     * 儲存資料-隨機生成資料ID
     *
     * @param index     索引
     * @param dataValue 資料內容
     */
    public IndexResponse save(String index, Object dataValue) {
        try {
            IndexRequest request = new IndexRequest(index);
            request.source(JSON.toJSONString(dataValue), XContentType.JSON);
            return restHighLevelClient.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> save exception ,index = {},dataValue={} ,stack={}", index, dataValue, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> save exception {}", e);
        }
    }

    /**
     * 儲存文件-自定義資料ID
     *
     * @param index     索引
     * @param id        資料ID
     * @param dataValue 資料內容
     */
    public IndexResponse save(String index, String id, Object dataValue) {
        return this.saveOrUpdate(index, id, dataValue);
    }

    /**
     * 儲存文件-自定義資料ID
     * <p>
     * 如果文件存在,則更新文件;如果文件不存在,則儲存文件。
     *
     * @param index     索引
     * @param id        資料ID
     * @param dataValue 資料內容
     */
    public IndexResponse saveOrUpdate(String index, String id, Object dataValue) {
        try {
            IndexRequest request = new IndexRequest(index);
            request.id(id);
            request.source(JSON.toJSONString(dataValue), XContentType.JSON);
            return restHighLevelClient.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> save exception ,index = {},dataValue={} ,stack={}", index, dataValue, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> save exception {}", e);
        }
    }

    /**
     * 批量-新增或儲存文件
     * <p>
     * 如果集合中有些文件已經存在,則更新文件;不存在,則儲存文件。
     *
     * @param index        索引
     * @param documentList 文件集合
     */
    public void batchSaveOrUpdate(String index, List<ElasticSearchDocModel<?>> documentList) {
        if (CollectionUtils.isEmpty(documentList)) {
            return;
        }
        try {
            // 批量請求
            BulkRequest bulkRequest = new BulkRequest();
            documentList.forEach(doc -> bulkRequest.add(new IndexRequest(index)
                    .id(doc.getId())
                    .source(JSON.toJSONString(doc.getData()), XContentType.JSON)));
            restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> batchSave exception ,index = {},documentList={} ,stack={}", index, documentList, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> batchSave exception {}", e);
        }
    }

    /**
     * 根據ID修改
     *
     * @param index     索引
     * @param id        資料ID
     * @param dataValue 資料內容
     */
    public UpdateResponse updateById(String index, String id, Object dataValue) {
        try {
            UpdateRequest request = new UpdateRequest(index, id);
            request.doc(JSON.toJSONString(dataValue), XContentType.JSON);
            return restHighLevelClient.update(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> updateById exception ,index = {},dataValue={} ,stack={}", index, dataValue, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> updateById exception {}", e);
        }
    }

    /**
     * 部分修改()
     * 注:1).可變更已有欄位值,可新增欄位,刪除欄位無效
     * 2).若當前ID資料不存在則新增
     *
     * @param index     索引
     * @param id        資料ID
     * @param dataValue 資料內容
     */
    public UpdateResponse updateByIdSelective(String index, String id, Object dataValue) {
        try {
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(dataValue));
            UpdateRequest request = new UpdateRequest(index, id)
                    .doc(jsonObject)
                    .upsert(jsonObject);
            return restHighLevelClient.update(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> updateByIdSelective exception ,index = {},dataValue={} ,stack={}", index, dataValue, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> updateByIdSelective exception {}", e);
        }
    }

    /**
     * 根據id查詢
     *
     * @param index 索引
     * @param id    資料ID
     * @return T
     */
    public <T> T getById(String index, String id, Class<T> clazz) {
        GetResponse getResponse = this.getById(index, id);
        if (null == getResponse) {
            return null;
        }
        return JSON.parseObject(getResponse.getSourceAsString(), clazz);
    }

    /**
     * 根據id集批量獲取資料
     *
     * @param index  索引
     * @param idList 資料ID集
     * @return T
     */
    public <T> List<T> getByIdList(String index, List<String> idList, Class<T> clazz) {
        MultiGetItemResponse[] responses = this.getByIdList(index, idList);
        if (null == responses || responses.length == 0) {
            return new ArrayList<>(0);
        }

        List<T> resultList = new ArrayList<>(responses.length);
        for (MultiGetItemResponse response : responses) {
            GetResponse getResponse = response.getResponse();
            if (!getResponse.isExists()) {
                continue;
            }
            resultList.add(JSON.parseObject(getResponse.getSourceAsString(), clazz));
        }

        return resultList;
    }

    /**
     * 根據多條件查詢--分頁
     * 注:from-size -[ "淺"分頁 ]
     *
     * @param index    索引
     * @param pageNo   頁碼(第幾頁)
     * @param pageSize 頁容量- Elasticsearch預設配置單次最大限制10000
     */
    public <T> List<T> searchPageByIndex(String index, Integer pageNo, Integer pageSize, Class<T> clazz) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(PageUtils.getStartRow(pageNo, pageSize));
        searchSourceBuilder.size(pageSize);

        return this.searchByQuery(index, searchSourceBuilder, clazz);
    }

    /**
     * 條件查詢
     *
     * @param index         索引
     * @param sourceBuilder 條件查詢構建起
     * @param <T>           資料型別
     * @return T 型別的集合
     */
    public <T> List<T> searchByQuery(String index, SearchSourceBuilder sourceBuilder, Class<T> clazz) {
        try {
            // 構建查詢請求
            SearchRequest searchRequest = new SearchRequest(index).source(sourceBuilder);
            // 獲取返回值
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHit[] hits = response.getHits().getHits();
            if (null == hits || hits.length == 0) {
                return new ArrayList<>(0);
            }

            List<T> resultList = new ArrayList<>(hits.length);
            for (SearchHit hit : hits) {
                resultList.add(JSON.parseObject(hit.getSourceAsString(), clazz));
            }
            return resultList;
        } catch (ElasticsearchStatusException e) {
            //索引不存在
            if (e.status() == RestStatus.NOT_FOUND) {
                log.error("[ elasticsearch ] >>  searchByQuery exception >>  index:{}, Not found ", index, e);
                return new ArrayList<>(0);
            }
            throw new ElasticSearchRunException("[ elasticsearch ] >> searchByQuery exception {}", e);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> searchByQuery exception ,index = {},sourceBuilder={} ,stack={}", index, sourceBuilder, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> searchByQuery exception {}", e);
        }
    }


    /**
     * 根據ID刪除文件
     *
     * @param index 索引
     * @param id    文件ID
     * @return 是否刪除成功
     */
    public boolean deleteById(String index, String id) {
        try {
            DeleteRequest request = new DeleteRequest(index, id);
            DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
            //未找到檔案
            if (response.getResult() == DocWriteResponse.Result.NOT_FOUND) {
                log.error("[ elasticsearch ] >> deleteById document is not found , index:{},id:{}", index, id);
                return false;
            }
            return RestStatus.OK.equals(response.status());
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> deleteById exception ,index:{},id:{} ,stack:{}", index, id, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> deleteById exception {}", e);
        }
    }

    /**
     * 根據查詢條件刪除文件
     *
     * @param index        索引
     * @param queryBuilder 查詢條件構建器
     */
    public void deleteByQuery(String index, QueryBuilder queryBuilder) {
        try {
            DeleteByQueryRequest request = new DeleteByQueryRequest(index).setQuery(queryBuilder);
            request.setConflicts("proceed");
            restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> deleteByQuery exception ,index = {},queryBuilder={} ,stack={}", index, queryBuilder, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> deleteByQuery exception {}", e);
        }
    }

    /**
     * 根據文件 ID 批量刪除文件
     *
     * @param index  索引
     * @param idList 文件 ID 集合
     */
    public void deleteByIdList(String index, List<String> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return;
        }
        try {
            BulkRequest bulkRequest = new BulkRequest();
            idList.forEach(id -> bulkRequest.add(new DeleteRequest(index, id)));
            restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> deleteByIdList exception ,index = {},idList={} ,stack={}", index, idList, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> deleteByIdList exception {}", e);
        }
    }

    /**
     * 根據id查詢
     *
     * @param index 索引
     * @param id    文件ID
     * @return GetResponse
     */
    private GetResponse getById(String index, String id) {
        try {
            GetRequest request = new GetRequest(index, id);
            return restHighLevelClient.get(request, RequestOptions.DEFAULT);
        } catch (ElasticsearchException e) {
            if (e.status() == RestStatus.NOT_FOUND) {
                log.error("[ elasticsearch ] >> getById document not found ,index = {},id={} ,stack={}", index, id, e);
                return null;
            }
            throw new ElasticSearchRunException("[ elasticsearch ] >> getById exception {}", e);
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> getById exception ,index = {},id={} ,stack={}", index, id, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> getById exception {}", e);
        }
    }

    /**
     * 根據id集-批量獲取資料
     *
     * @param index  索引
     * @param idList 資料文件ID集
     * @return MultiGetItemResponse[]
     */
    private MultiGetItemResponse[] getByIdList(String index, List<String> idList) {
        try {
            MultiGetRequest request = new MultiGetRequest();
            for (String id : idList) {
                request.add(new MultiGetRequest.Item(index, id));
            }

            //同步執行
            MultiGetResponse responses = restHighLevelClient.mget(request, RequestOptions.DEFAULT);
            return responses.getResponses();
        } catch (IOException e) {
            log.error("[ elasticsearch ] >> getByIdList exception ,index = {},idList={} ,stack={}", index, idList, e);
            throw new ElasticSearchRunException("[ elasticsearch ] >> getByIdList exception {}", e);
        }
    }
}

7.測試

7.1建立測試物件

/**
 * 人員資訊實體類
 */
@Data
public class UserInfo implements Serializable {

    private static final long serialVersionUID = 8802812229085206905L;

    /**
     * 使用者ID
     */
    private String userId;

    /**
     * 使用者名稱
     */
    private String userName;

    /**
     * 真實姓名
     */
    private String realName;

    /**
     * 手機號
     */
    private String mobile;

    /**
     * 年齡
     */
    private Integer age;

    /**
     * 成績分值
     * 注:小數測試
     */
    private BigDecimal grades;

    /**
     * 建立時間
     */
    private Date createTime;

}

7.2索引Index操作

/**
 * ElasticSearch 索引相關測試
 *
 * @author 程式設計師小強
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ElasticSearchIndexTest {

    @Autowired
    private ElasticSearchRestApiClient elasticSearchIndexClient;

    /**
     * 判斷索引是否存在
     */
    @Test
    public void existsIndex() {
        String index = "test_index2";
        boolean exists = elasticSearchIndexClient.existsIndex(index);
        System.out.println(String.format("判斷索引是否存在, index:%s , 是否存在:%b", index, exists));
    }

    /**
     * 建立 ES 索引
     */
    @Test
    public void createIndex() {
        String index = "test_index2";
        //文件屬性Mapping集
        Map<String, Object> message = new HashMap<>();
        message.put("type", "text");

        Map<String, Object> value = new HashMap<>();
        value.put("type", "keyword");

        Map<String, Object> properties = new HashMap<>();
        properties.put("message", message);
        properties.put("value", value);

        boolean createIndexFlag = elasticSearchIndexClient.createIndex(index, properties);
        System.out.println(String.format("建立索引, index:%s , createIndexFlag:%b", index, createIndexFlag));
    }

    /**
     * 獲取索引配置
     */
    @Test
    public void getIndexSetting() {
        String index = "test_index2";
        GetSettingsResponse response = elasticSearchIndexClient.getIndexSetting(index);
        System.out.println(String.format("獲取索引配置, index:%s", index));
        System.out.println(response);
    }


    /**
     * 刪除索引
     */
    @Test
    public void deleteIndex() {
        String index = "test_index2";
        boolean deleteIndexFlag = elasticSearchIndexClient.deleteIndex(index);
        System.out.println(String.format("刪除索引, index:%s , deleteIndexFlag:%b", index, deleteIndexFlag));
    }
}

7.3CRUD操作

/**
 * ElasticSearch 文件-增刪改測試
 *
 * @author 程式設計師小強
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ElasticSearchCrudTest {

    @Autowired
    private ElasticSearchRestApiClient elasticSearchIndexClient;

    private static final String INDEX = "test_index";

    /**
     * 判斷索引是否存在
     */
    @Test
    public void existsIndex() {
        String index = "test_index";
        boolean exists = elasticSearchIndexClient.existsIndex(index);
        System.out.println(String.format("判斷索引是否存在, index:%s , 是否存在:%b", index, exists));
    }

    /**
     * 判斷文件是否存在
     */
    @Test
    public void existsDocument() {
        String index = "test_index";
        String id = "9de70a8227c3420bbe6f22b5135b8123";
        boolean exists = elasticSearchIndexClient.existsDocument(index, id);
        System.out.println(String.format("判斷文件是否存在, index:%s , id:%s, 是否存在:%b", index, id, exists));
    }

    /**
     * 儲存資料-自定義資料ID
     */
    @Test
    public void save() {
        String userId = getUuId();
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName("lisi2");
        userInfo.setRealName("李四2");
        userInfo.setMobile("13725353777");
        userInfo.setAge(21);
        userInfo.setGrades(new BigDecimal("550.09"));
        userInfo.setCreateTime(new Date());
        IndexResponse response = elasticSearchIndexClient.save(INDEX, userId, userInfo);
        System.out.println(String.format("資料儲存完畢, id:%s", response.getId()));

        UserInfo userInfo1 = elasticSearchIndexClient.getById(INDEX, userId, UserInfo.class);
        System.out.println(String.format("查詢結果:%s", response.getId()));
        System.out.println(JSON.toJSONString(userInfo1, SerializerFeature.PrettyFormat));
    }

    /**
     * 批量儲存資料-自定義資料ID
     */
    @Test
    public void batchSave() {
        List<ElasticSearchDocModel<?>> documentList = new ArrayList<>();
        UserInfo userInfo = null;
        for (int i = 0; i <= 5; i++) {
            String userId = getUuId();
            userInfo = new UserInfo();
            userInfo.setUserId(userId);
            userInfo.setUserName("zhangsan");
            userInfo.setRealName("我是" + i);
            userInfo.setMobile("15725353777");
            userInfo.setAge(20);
            userInfo.setGrades(new BigDecimal("690.09"));
            userInfo.setCreateTime(new Date());
            documentList.add(new ElasticSearchDocModel<>(userId, userInfo));
        }

        elasticSearchIndexClient.batchSaveOrUpdate(INDEX, documentList);
        System.out.println("批量儲存資料結束");
    }

    /**
     * 根據ID修改
     */
    @Test
    public void updateById() {
        String userId = "9de70a8227c3420bbe6f22b5135b8123";
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName("zhangsan2");
        userInfo.setRealName("張三2");
        userInfo.setMobile("15725353777");
        userInfo.setAge(22);
        userInfo.setGrades(new BigDecimal("580.09"));
        userInfo.setCreateTime(new Date());

        UpdateResponse updateResponse = elasticSearchIndexClient.updateById(INDEX, userId, userInfo);
        System.out.println(String.format("修改的資料 ID:%s, 版本:%d", updateResponse.getId(), updateResponse.getVersion()));

    }

    /**
     * 根據ID部分修改
     */
    @Test
    public void updateByIdSelective() {
        String userId = "9de70a8227c3420bbe6f22b5135b8123";
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setMobile("15725353777");
        userInfo.setAge(23);
        userInfo.setGrades(new BigDecimal("581.09"));

        UpdateResponse updateResponse = elasticSearchIndexClient.updateByIdSelective(INDEX, userId, userInfo);
        System.out.println(String.format("修改的資料 ID:%s, 版本:%d", updateResponse.getId(), updateResponse.getVersion()));

    }

    /**
     * 根據id集批量獲取資料
     */
    @Test
    public void getByIdList() {
        List<String> idList = new ArrayList<>();
        idList.add("9de70a8227c3420bbe6f22b5135b8123");
        idList.add("d707b8637a724ff09b9c1591d8a33576");
        List<UserInfo> userInfoList = elasticSearchIndexClient.getByIdList(INDEX, idList, UserInfo.class);
        System.out.println("批量查詢結果");
        System.out.println(JSON.toJSONString(userInfoList, SerializerFeature.PrettyFormat));
    }


    /**
     * 根據ID刪除
     */
    @Test
    public void deleteById() {
        String userId = "d707b8637a724ff09b9c1591d8a33576";
        boolean deleteFlag = elasticSearchIndexClient.deleteById(INDEX, userId);
        System.out.println(String.format("判斷索引是否存在, index:%s , 是否存在:%b", userId, deleteFlag));
    }

    /**
     * 根據文件 ID 批量刪除文件
     */
    @Test
    public void deleteByIdList() {
        List<String> idList = new ArrayList<>();
        idList.add("b824025525004e048a34c2398931183d");
        idList.add("5053444f587145e5af5d866245653a5e");
        elasticSearchIndexClient.deleteByIdList(INDEX, idList);
        System.out.println("批量刪除文件完成");
    }

    public String getUuId() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
    
}

7.4查詢例項

/**
 * ElasticSearch 查詢測試
 *
 * @author 程式設計師小強
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ElasticSearchQueryTest {

    @Autowired
    private ElasticSearchRestApiClient elasticSearchRestClient;

    private static final String INDEX = "test_index";

    /**
     * 分頁查詢
     * 使用,from-size 的"淺"分頁
     */
    @Test
    public void searchPageByIndex() {
        int pageNo = 2;
        int pageSize = 2;
        List<UserInfo> dataList = elasticSearchRestClient.searchPageByIndex(INDEX, pageNo, pageSize, UserInfo.class);

        System.out.println(String.format("分頁查詢, pageNo:%d , pageSize:%d", pageNo, pageSize));
        System.out.println(JSON.toJSONString(dataList, SerializerFeature.PrettyFormat));

    }


    /**
     * 聚合條件查詢
     */
    @Test
    public void searchByQuery() {
        int pageNo = 1;
        int pageSize = 10;

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分頁引數
        searchSourceBuilder.from(PageUtils.getStartRow(pageNo, pageSize));
        searchSourceBuilder.size(pageSize);

        // bool 查詢
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        searchSourceBuilder.query(boolQueryBuilder);

        //排序
        searchSourceBuilder.sort("age");

        List<UserInfo> dataList = elasticSearchRestClient.searchByQuery(INDEX, searchSourceBuilder, UserInfo.class);

        System.out.println(String.format("聚合條件查詢, searchSourceBuilder:%s", searchSourceBuilder));
        System.out.println(String.format("集合大小, dataListSize:%d", dataList.size()));
        System.out.println(JSON.toJSONString(dataList, SerializerFeature.PrettyFormat));
    }
}

8.原始碼地址

傳送門

關注程式設計師小強公眾號更多程式設計趣事,知識心得與您分享