RestClient operation ES document

Create a test class and do two things:

  • Initialize RestHighLevelClient

  • Our hotel data is in the database and needs to be queried by IHotelService, so we inject this interface

import cn.pino.hotel.pojo.Hotel;
import cn.pino.hotel.service.IHotelService;
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;

@SpringBootTest
public class HotelDocumentTest {
    @Autowired
    private IHotelService hotelService;

    private RestHighLevelClient client;

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://127.0.0.1:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

  

1. Add a document

We need to query the hotel data in the database and write it into elasticsearch.

Index library entity class

The result of the database query is an object of type Hotel. The structure is as follows:

@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;
}

  

There are differences with our index library structure:

  • longitude and latitude need to be merged into location

Therefore, we need to define a new type, which is consistent with the index library structure:

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();
    }
}

  

Syntax description

The DSL statement of the new document is as follows:

POST /{Index library name}/_doc/1
{
    "name": "Jack",
    "age": 21
}

The corresponding java code is shown in the figure below:

 

Complete code

 

 

@Test
void testAddDocument() throws IOException {
    // 1. Query hotel data according to id
    Hotel hotel = hotelService.getById(61083L);
    // 2. Convert to document type
    HotelDoc hotelDoc = new HotelDoc(hotel);
    // 3. Transfer HotelDoc to json
    String json = JSON.toJSONString(hotelDoc);

    // 1. Prepare the Request object
    IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
    // 2. Prepare Json documents
    request.source(json, XContentType.JSON);
    // 3. Send request
    client.index(request, RequestOptions.DEFAULT);
}

  

2. Query documents

The DSL statement of query is as follows:

GET /hotel/_doc/{id}

  

Very simple, so the code is roughly divided into two steps:

  • Prepare Request object

  • Send request

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

 

 

 

Complete code

@Test
void testGetDocumentById() throws IOException {
    // 1. Prepare Request
    GetRequest request = new GetRequest("hotel", "61082");
    // 2. Send a request and get a response
    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    // 3. Analyze the response results
    String json = response.getSourceAsString();

    HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    System.out.println(hotelDoc);
}

  

3. Delete document

The deleted DSL is as follows:

DELETE /hotel/_doc/{id}

  

Full code:

@Test
void testDeleteDocument() throws IOException {
    // 1. Prepare Request
    DeleteRequest request = new DeleteRequest("hotel", "61083");
    // 2. Send request
    client.delete(request, RequestOptions.DEFAULT);
}

  

4. Modify the document

Syntax description

There are two ways to modify:

  • Full quantity modification: in essence, it is deleted according to the id and then added

  • Incremental modification: modifies the specified field value in the document

 

In the RestClient API, the total modification is completely consistent with the newly added API. The judgment basis is ID:

  • If the ID already exists when adding, it can be modified

  • If the ID does not exist when adding, add

We will not repeat it here. We mainly focus on incremental modification.

The code example is shown in the figure below:

 

 

 

Complete code

@Test
void testUpdateDocument() throws IOException {
    // 1. Prepare Request
    UpdateRequest request = new UpdateRequest("hotel", "61083");
    // 2. Prepare request parameters
    request.doc(
        "price", "952",
        "starName", "Four drill"
    );
    // 3. Send request
    client.update(request, RequestOptions.DEFAULT);
}

  

5. Batch import documents

The steps are as follows:

  • Query hotel data with mybatis plus

  • Convert the queried Hotel data (Hotel) to document type data (HotelDoc)

  • The BulkRequest batch processing in JavaRestClient is used to realize batch addition of documents

 

Syntax description

The essence of bulk request processing is to send multiple ordinary CRUD requests together.

An add method is provided to add other requests:

 

 

 

You can see that the requests that can be added include:

  • IndexRequest, i.e. new

  • UpdateRequest, that is, modify

  • DeleteRequest, that is, delete

Therefore, adding multiple indexrequests to Bulk is a new function in batch.

Complete code

When importing hotel data, we can transform the above code into a for loop.

@Test
void testBulkRequest() throws IOException {
    // Batch query of hotel data
    List<Hotel> hotels = hotelService.list();

    // 1. Create a Request
    BulkRequest request = new BulkRequest();
    // 2. Prepare parameters and add multiple new requests
    for (Hotel hotel : hotels) {
        // 2.1. Convert to document type HotelDoc
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 2.2. Create a Request object for a new document
        request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    }
    // 3. Send request
    client.bulk(request, RequestOptions.DEFAULT);
}

  

Summary

Basic steps of document operation:

  • Initialize RestHighLevelClient

  • Create an XxxRequest. XXX is Index, Get, Update, Delete, Bulk

  • Prepare parameters (required for Index, Update and Bulk)

  • Send request. Call RestHighLevelClient#.xxx() method, where xxx is index, get, update, delete and bulk

  • Parsing results (required for Get)

 

Tags: ElasticSearch

Posted on Mon, 08 Nov 2021 21:50:35 -0500 by Buttero