Microservice Distributed Search Engine Elastic Search RestClient Operation Documentation

Article directory

  • ?introduction
  • 1. Initialize Java RestClient
  • 2. RestClient’s CRUD operation on documents
    • ?New document
    • ?Query documents
    • ? Modify the document
    • ?Delete documents
  • 3. RestClient Batch Document Import
  • ?summary

?Introduction

This article refers to the dark horse distributed Elastic search
Elasticsearch is a very powerful open source search engine with many powerful functions that can help us quickly find what we need from massive amounts of data

1. Initialize Java RestClient

Initialize RestHighLevelClient

In order to separate from the index library operation, we add a test class again, which does two things:

  • Initialize RestHighLevelClient
  • Our hotel data is in the database, we need to use IHotelService to query, so inject this interface

Document test class

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
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.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.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.List;

/**
 * @author whc
 * @date 2023/2/28 15:01
 */
@SpringBootTest
public class HotelDocumentTest {<!-- -->

    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private IHotelService hotelService;

    @BeforeEach
    void setUp() {<!-- -->
           this.restHighLevelClient = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("IP address: 9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {<!-- -->
        this.restHighLevelClient.close();
    }
}

The test class initialization RestClient is completed.

2. RestClient CRUD operations on documents

Next, we use RestClient to add, delete, modify and check the document for a deeper understanding.

?Add document

Requirement: Query the hotel data from the database and write it into ElasticSearch through RestClient.

Conversion between entity class and index library entity class

The result returned by the database is a Hotel type object with the following properties:

@Data
@TableName("tb_hotel")
public class Hotel {<!-- -->
    @TableId(type = IdType. INPUT)
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String longitude;
    private String latitude;
    private String pic;
}

Then the question is, what should we do if the structure of our ElasticSearch index library is inconsistent with the entity class?

For example: longitude and latitude are realized by location in the index library, separated by , . In the entity class there are two separate properties.

Therefore, we need to define a new object and combine the properties to achieve the result we want

import lombok. Data;
import lombok. NoArgsConstructor;

@Data
@NoArgsConstructor
public class HotelDoc {<!-- -->
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String location;
    private String pic;

    public HotelDoc(Hotel hotel) {<!-- -->
        this.id = hotel.getId();
        this.name = hotel.getName();
        this.address = hotel.getAddress();
        this.price = hotel.getPrice();
        this.score = hotel.getScore();
        this.brand = hotel.getBrand();
        this.city = hotel.getCity();
        this.starName = hotel.getStarName();
        this. business = hotel. getBusiness();
        this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
        this.pic = hotel.getPic();
    }
}

Grammar Description

The DSL statement of the newly added document is as follows:

POST /{<!-- -->Index library name}/_doc/1
{<!-- -->
    "name": "Jack",
    "age": 20
}

The Java code is as follows

You can see that it is similar to creating an index library, and it is also a three-step process:

  • 1. Create a Request object
  • 2. Prepare request parameters, that is, JSON in DSL document
  • 3. Send request

The change is that the API of **client.xxx() is directly used here, and there is no need forclient.indices()**.

New documentation for full code testing

@Test
void testAddDocument() throws IOException {<!-- -->
    //Get hotel data
    Hotel hotel = hotelService. getById(36934L);
HotelDoc hotelDoc = new HotelDoc(hotel);
//1. Create a request object
    IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
    //2. Prepare parameters
    request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
    //3. Send request
    restHighLevelClient.index(request, RequestOptions.DEFAULT);
}

Just execute it.

?Query document

The query DSL statement is as follows:

GET /index library name/_doc/{<!-- -->id}

Roughly divided into 2 steps

  • Prepare the Request object
  • send request

However, the purpose of the query is to get the result, which is parsed into HotelDoc, so the difficulty is the parsing of the result. The complete code is as follows:

As you can see, the result is a JSON, in which the document is placed in a _source attribute, so the parsing is to get the _source, and deserialize it into a Java object can be.

Similar to before, it is also divided into three steps

  • 1. Prepare the Request object. This time it’s a query, so GetRequest
  • 2. Send the request and get the result. Because it is a query, the client.get() method is called here
  • 3. The result of the analysis is to deserialize the JSON

Full code

@Test
void testGetDocument() throws IOException {<!-- -->
    //1. Create a request object
    GetRequest request = new GetRequest("hotel", "36934");
    //2. Send request
    GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
    String sourceAsString = response. getSourceAsString();
    System.out.println(sourceAsString);
}

The results are as follows:

?Modify document

The modification is divided into two ways:

  • Full modification: the essence is to delete according to the id first, and then add
  • Incremental modification: Modify the specified field value in the document

In the RestClient API, the full modification is exactly the same as the newly added API, and the judgment is based on the ID:

  • If the ID already exists when adding, modify it
  • If the ID does not exist when adding, add it

Here we mainly introduce incremental modification

The code example is as follows:

Similar to before, it is mainly divided into three steps

  • 1. Prepare the Request object. This time it is a modification, so UpdateRequest
  • 2. Prepare parameters. That is, the JSON document, which contains the fields to be modified
  • 3. Update the documentation. Call the client.update() method here

Full code

@Test
void testUpdateDocument() throws IOException {<!-- -->
    //1. Create a request object
    UpdateRequest request = new UpdateRequest("hotel", "36934");
    //2. Prepare parameters
    request.doc(
        "price", "456",
        "starName", "Three Diamonds"
    );
    //3. Send request
    restHighLevelClient.update(request, RequestOptions.DEFAULT);
}

Modify results

After the modification is completed, view the modification result through the get request again

?Delete document

The DSL for removal is something like this:

DELETE /hotel/_doc/{<!-- -->id}

Compared with the query, only the request method changes from DELETE to GET. It can be imagined that the Java code should still be divided into three steps:

  • 1. Prepare the Request object, because it is deleted, this time it is the DeleteRequest object. To specify the index library name and id
  • 2. Prepare parameters, no parameters
  • 3. Send the request. Because it is deleted, it is the client.delete() method

Full Java code

@Test
void testDeleteDocument() throws IOException {<!-- -->
    //1. Create a request object
    DeleteRequest request = new DeleteRequest("hotel", "36934");
    //2. Send request
    restHighLevelClient.delete(request, RequestOptions.DEFAULT);
}

View deletion results

After the execution is complete, call the get request to view the result

3. RestClient batch document import

Requirement: Use BulkRequest to batch import database data into the index library.

Proceed as follows:

  • Use mybatis-plus to query hotel data
  • Convert the queried hotel data (Hotel) to document type data (HotelDoc)
  • Use BulkRequest batch processing in JavaRestClient to realize batch adding documents

The essence of batch processing BulkRequest is to combine and send multiple ordinary CRUD requests together.

It provides an add method to add other requests

As you can see, the requests that can be added include:

  • IndexRequest, which is to add
  • UpdateRequest, which is to modify
  • DeleteRequest, that is, delete

Therefore, multiple IndexRequest are added in Bulk, which is the function of batch adding. Example:

It is still divided into three steps:

  • 1. Create a Request object. Here is the BulkRequest
  • 2. Prepare parameters. The parameters of batch processing are other Request objects, here are multiple IndexRequests
  • 3. Initiate a request. Here is batch processing, the method called is client.bulk() method

After importing the hotel data, just change the code to a for loop

Full Java code

@Test
void testBulk() throws IOException {<!-- -->
    //Get hotel data
    List<Hotel> hotels = hotelService. list();

    //1. Create a bulk request
    BulkRequest request = new BulkRequest();
    //2. Add batch processing requests
    for (Hotel hotel : hotels) {<!-- -->
        HotelDoc hotelDoc = new HotelDoc(hotel);
        request. add(new IndexRequest("hotel").
                    id(hotel.getId().toString()).source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    }

    //3. Send request
    restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
}

View execution results

After the execution is complete, execute the following DSL statement to query in batches

The execution is complete and the import is successful.

?Summary

The above is [Bug Terminator]’s brief introduction to Microservice Distributed Search Engine Elastic Search RestClient Operation Document, ES search engine is undoubtedly the best distributed Search engine, using it, can greatly improve the flexibility and efficiency of the project! Technology changes the world! ! !

If this [article] is helpful to you, I hope you can give [Bug Terminator] a thumbs up It’s not easy to create. 、【Front-end field】Interested cuties are also welcome to pay attention 【Bug Terminator】, I will give You bring huge [harvests and surprises]!

syntaxbug.com © 2021 All Rights Reserved.