ElasticSearch is a Lucene-based search server. It provides a distributed multi – user – capable full – text search engine based on RESTful Web interface. Elasticsearch, developed in the Java language and released as open source under the Apache license, is a popular enterprise-level search engine. ElasticSearch is available in the cloud for real-time search, stability, reliability, speed, and ease of installation. Official clients are available in Java,.NET, PHP, Python, Apache Groovy, Ruby, and many other languages.

This article describes how Spring Boot integrates ElasticSearch with the ElasticSearch search engine and uses the Java High-level REST Client provided by ElasticSearch.

Environment to prepare

  • ElasticSearch 7.5.1
  • Spring Boot 2.1.9

The first step is to install the ElasticSearch environment, and it is best to install a ElasticSearch visual interface (the ElasticSearch Head plugin is recommended) so that you can view the data.

ElasticSearch Head for ElasticSearch with Widows: ElasticSearch Head for ElasticSearch with Widows: ElasticSearch Head

Add the dependent

In the pom. XML file, add the Java High Level REST Client dependencies provided by ElasticSearch.

Note: When adding ElasticSearch dependencies, be sure to specify the version number. If the version number is not specified, the system directly inherits the Version number of Spring Boot. As a result, the version of ElasticSearch is inconsistent with that of ElasticSearch and an error occurs.

<! -- ElasticSearch High Level Client -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.5.1</version>
</dependency>

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.5.1</version>
</dependency>

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.5.1</version>
</dependency>
<! -- ./ ElasticSearch High Level Client -->
Copy the code

Configuration RestHighLevelClient

RestHighLevelClient is configured to operate ElasticSearch.

/**
 * EsRestHighLevelClient
 *
 * @author star
 */
@Configuration
public class EsRestHighLevelClientConfig {

    @Value("${spring.elasticsearch.rest.scheme}")
    private String scheme;

    @Value("${spring.elasticsearch.rest.ip-address}")
    private List<String> ipAddressList;

    @Bean
    public RestHighLevelClient restHighLevelClient(a) {
        return new RestHighLevelClient(RestClient.builder(this.createHttpHost()));
    }

    /** * Create an HttpHost object **@returnReturns HttpHost object array */
    privateHttpHost[] createHttpHost() { Asserts.check(! CollectionUtils.isEmpty(ipAddressList),"ElasticSearch cluster ip address cannot empty");

        HttpHost[] httpHosts = new HttpHost[ipAddressList.size()];
        for (int i = 0, len = ipAddressList.size(); i < len; i++) {
            String ipAddress = ipAddressList.get(i);
            String[] values = ipAddress.split(":");

            String ip = values[0];
            int port = Integer.parseInt(values[1]);
            / / create HttpHost
            httpHosts[i] = new HttpHost(ip, port, scheme);
        }

        returnhttpHosts; }}Copy the code

Write ElaticSearch related apis

  • Index creation

ElaticSearch 7.x deprecated mapping and deprecated type, where an index is equivalent to a table.

See the official documentation on mapping Type removal for details. The following is a description of the mapping type for ElaticSearch 7.x:

/** * create ES index **@paramThe index index *@paramProperties Collection of document properties *@returnReturns true, indicating a successful creation *@throws IOException
  */
public boolean createIndex(String index, Map<String, Map<String, Object>> properties) throws IOException {
    XContentBuilder builder = XContentFactory.jsonBuilder();
    In ES 7.0 or later, type is deprecated
    builder.startObject()
            .startObject("mappings")
            .field("properties", properties)
            .endObject()
            .startObject("settings")
            .field("number_of_shards", DEFAUT_SHARDS)
            .field("number_of_replicas", DEFAUT_REPLICAS)
            .endObject()
            .endObject();

    CreateIndexRequest request = new CreateIndexRequest(index).source(builder);
    CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);

    return response.isAcknowledged();
}
Copy the code
  • Check whether the index exists
/** * check whether the index exists **@paramThe index index *@returnReturns true, indicating the presence of */ 
public boolean isExistIndex(String index) throws IOException {
    GetIndexRequest getIndexRequest = new GetIndexRequest(index);
    getIndexRequest.local(false);
    getIndexRequest.humanReadable(true);
    getIndexRequest.includeDefaults(false);

    return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
}
Copy the code
  • Remove the index
/** * drop index **@paramThe index index *@returnReturns true, indicating successful deletion */
public boolean deleteIndex(String index) throws IOException {
    try {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);

        return response.isAcknowledged();
    } catch (ElasticsearchException exception) {
        if (exception.status() == RestStatus.NOT_FOUND) {
            throw new NotFoundException("Not found index: " + index);
        }

        throwexception; }}Copy the code
  • Save the document
/** * save the document * <p> * Update the document if it exists; If the document does not exist, save it. * *@paramDocument Document data */
public void save(String index, ElasticSearchDocument
        document) throws IOException {
    IndexRequest indexRequest = new IndexRequest(index);
    indexRequest.id(document.getId());
    indexRequest.source(JSON.toJSONString(document.getData()), XContentType.JSON);
    // Save the document data
    restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);

}

/** * Update documents if some documents in the collection already exist; If no, save the document. * *@paramThe index index *@paramDocumentList Document collection */
public void saveAll(String index, List
       
        > documentList)
       > throws IOException {
    if (CollectionUtils.isEmpty(documentList)) {
        return;
    }
    // Batch requests
    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);

}
Copy the code
  • Delete the document
/** * Delete document ** according to document ID@paramThe index index *@paramId Document ID */
public void delete(String index, String id) throws IOException {
    DeleteRequest deleteRequest = new DeleteRequest(index, id);

    restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
}

/** * Delete documents according to query criteria **@paramThe index index *@paramQueryBuilder query condition builder */
public void deleteByQuery(String index, QueryBuilder queryBuilder) throws IOException {
    DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(index).setQuery(queryBuilder);
    deleteRequest.setConflicts("proceed");

    restHighLevelClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);

}

/** * Delete documents ** in batches according to the document ID@paramThe index index *@paramIdList Document ID collection */
public void deleteAll(String index, List<String> idList) throws IOException {
    if (CollectionUtils.isEmpty(idList)) {
        return;
    }
    BulkRequest bulkRequest = new BulkRequest();
    idList.forEach(id -> bulkRequest.add(new DeleteRequest(index, id)));

    restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
}
Copy the code
  • Get the document
/** * Retrieve data by index and document ID **@paramThe index index *@paramId Document ID *@param<T> Data type *@returnT returns data of type T */
public <T> T get(String index, String id, Class<T> resultType) throws IOException {
    GetRequest getRequest = new GetRequest(index, id);
    GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
    String resultAsString = response.getSourceAsString();

    return JSON.parseObject(resultAsString, resultType);
}

/** **@paramThe index index *@paramSourceBuilder conditional query builds *@param<T> Data type *@returnA collection of type T */
public <T> List<T> searchByQuery(String index, SearchSourceBuilder sourceBuilder, Class<T> resultType) throws IOException {
    // Build the query request
    SearchRequest searchRequest = new SearchRequest(index).source(sourceBuilder);
    // Get the return value
    SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHit[] hits = response.getHits().getHits();
    // Create an empty query result set
    List<T> results = new ArrayList<>(hits.length);
    for (SearchHit hit : hits) {
        // Get the data source as a string
        String sourceAsString = hit.getSourceAsString();
        results.add(JSON.parseObject(sourceAsString, resultType));
    }

    return results;

}
Copy the code

demo

  • Call the interface POST using Postmanhttp://localhost:8080/api/users/batchInsert 2 test data into ElasticSearch:

  • View data using the ElasticSearch Head visualization plugin:

  • Get data by ID:

  • Obtain data according to name:

reference

ElasticSearch Java Rest Client

ElasticSearch Reference

Spring Boot NoSQL Integration (ElasticSearch 7.3)

Afterword.

Due to their own limited ability, if there is a mistake or improper place, please also criticize and correct, study together!

Springboot-elasticsearch = springboot-elasticSearch = springboot-elasticSearch