RestClient operation document IV

RestClient operation document

preface:

Relationship between Document operation and mapper

The mapper mapping file specifies the specific field type, whether the index is required, and what is its word segmentation method

==Document operation (document) = = specify a specific information corresponding to our field. Our information needs to be split and indexed through the index library mapping file

1. New document

In order to separate from the operation of creating the index library, we participate in a test class HotelDocumentTest again and do two things:

  • Initialize RestHighLevelClient

  • Our hotel data is in the database. We need to use IHotelService to query the information in the database, so we inject this interface and use MP plug-ins to quickly develop queries

  • The original Hotel entity class we defined does not conform to the document creation format, because we need to define a new entity class to splice the longitude and latitude fields, and longitude and latitude need to be merged into location

    package cn.itcast.hotel.pojo;
    
    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();
        }
    }
    
    

New syntax description:

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

You can see that, similar to creating an index library, there are also three steps:

  • 1) Create Request object
  • 2) Prepare request parameters, that is, JSON documents in DSL
  • 3) Send request

The difference is that the client The API of XXX () no longer requires client Indices().

We import hotel data. The basic process is the same, but we need to consider several changes:
  • The hotel data comes from the database. We need to query it first to get the hotel object
  • hotel object needs to be converted to HotelDoc object
  • HotelDoc needs to be serialized into json format

Therefore, the overall steps of the code are as follows:

  • 1) Query Hotel data by id
  • 2) Encapsulate Hotel as HotelDoc
  • 3) Serialize HotelDoc to JSON
  • 4) Create an IndexRequest and specify the name and id of the index library
  • 5) Prepare request parameters, that is, JSON documents
  • 6) Send request
package cn.itcast.hotel;

import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.impl.HotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
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;


/**
 * Project Name: Hotel demo
 * Description: document operation
 *
 * @author zhong
 * @date 2022-06-02 12:58
 */
@SpringBootTest
public class HotelDocumentTest {
    /**
     * Query information injected into MP plug-in
     */
    @Autowired
    HotelService hotelService;

    private RestHighLevelClient client;

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

    /**
     * New document
     */
    @Test
    void testAddDocument() throws IOException {
        // Query hotel information
        Hotel hotel = hotelService.getById(38609L);
        System.out.println(hotel);
        // Converting document types
        HotelDoc hotelDoc = new HotelDoc(hotel);

        // 1. Create object
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
        // 2. Set json document
        request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        // 3. Send document
        client.index(request,RequestOptions.DEFAULT);
    }

    /**
     * Destroy after execution
     * @throws IOException
     */
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

Query the newly added document information according to the document id

# Query information under the document
GET /hotel/_doc/38609

The query results are as follows:

{
  "_index" : "hotel",
  "_type" : "_doc",
  "_id" : "38609",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "address" : "126 Guangling Second Road",
    "brand" : "Super 8",
    "business" : "Sichuan North Road business district",
    "city" : "Shanghai",
    "id" : 38609,
    "location" : "31.282444, 121.479385",
    "name" : "Super 8 Hotel(Shanghai Chifeng Road store)",
    "pic" : "https://m.tuniucdn.com/fb2/t1/G2/M00/DF/96/Cii-TFkx0ImIQZeiAAITil0LM7cAALCYwKXHQ4AAhOi377_w200_h200_c1_t0.jpg",
    "price" : 249,
    "score" : 35,
    "starName" : "Second drill"
  }
}

2. Query document

The DSL statements for query are 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 the query is to get the result and resolve it to HotelDoc, so the difficulty is the result resolution. The complete code is as follows:

/**
 * Query document information by id
 */
@Test
void testGetDocumentById() throws IOException {
    // 1. Prepare request
    GetRequest request = new GetRequest("hotel", "38609");
    // 2. Send request and get response
    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    // 3. Parse response over
    String sourceAsString = response.getSourceAsString();
    // 4. Return object type
    HotelDoc hotelDoc = JSON.parseObject(sourceAsString, HotelDoc.class);
    System.out.println("Results of query documents:"+hotelDoc);
}

As you can see, the result is a JSON, where the document is placed in a_ source attribute, so parsing is to get_ source, which can be deserialized as a Java object.

Similar to the previous three steps:

  • 1) Prepare the Request object. This is a query, so it is GetRequest
  • 2) Send the request and get the result. Because it is a query, the client Get() method
  • 3) The parsing result is to deserialize JSON

3. Delete document

The DSL to be deleted is as follows:

DELETE /hotel/_doc/{id}

Compared with query, just changing the request mode from DELETE to GET, you can imagine that the Java code should still follow three steps:

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

In the HotelDocumentTest test test class of the hotel demo, write a unit test:

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

4. Modify document

Syntax description

Modify the two methods we talked about:

  • Full quantity modification: in essence, it is first deleted according to the id and then added
  • Incremental modification: modify the specified field value in the document

In the RestClient API, the full modification is completely consistent with the newly added API. 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

We won't repeat it here. We mainly focus on global modification.

The codes are as follows:

/**
 * Modify code according to id
 */
@Test
void upDaupdateById() throws IOException {
    // 1. Prepare req
    UpdateRequest request = new UpdateRequest("hotel", "38609");
    // 2. Prepare modified parameters
    request.doc(
            "price","300",
            "city","Guangzhou"
    );
    // 3. Send request
    client.update(request, RequestOptions.DEFAULT);
}

5. deleting documents

/**
 * remove document
 */
@Test
void testDelectById() throws IOException {
    // 1. Get req
    DeleteRequest request = new DeleteRequest("hotel", "38609");
    // 2. Send request
    client.delete(request, RequestOptions.DEFAULT);
}

6. Batch import documents

Case requirements: use BulkRequest to import database data into the index library in batches.

The steps are as follows:

  • Query hotel data with mybatis plus

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

  • Using BulkRequest batch processing in JavaRestClient to realize batch addition of documents

6.1 grammar description

The essence of bulk processing BulkRequest is to send multiple common CRUD requests together.

An add method is provided to add other requests:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-miqcpHR9-1654156804602)(images/image-20220602153520940.png)]

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

  • IndexRequest, that is, adding
  • UpdateRequest, that is, modify
  • DeleteRequest, that is, delete

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

/**
 * Batch import data
 */
@Test
void testBulkRequest() throws IOException {
    // Call MP plug-in to query all data
    List<Hotel> hotelList = hotelService.list();
    // 1. Create request
    BulkRequest request = new BulkRequest();
    // 2. Package parameters, submitted together
    for (Hotel hotel : hotelList) {
        // Conversion type
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // Create object information of 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);
}

In fact, there are three steps:

  • 1) Create a Request object. This is BulkRequest
  • 2) Prepare parameters. Batch processing parameters are other Request objects. Here are multiple indexrequests
  • 3) Initiate a request. This is batch processing, and the called method is client Bulk() method

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

On the Dev Tools page, you can query all data through the following statements

# Query all data
GET /hotel/_search

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, xxx is index, get, update, delete, bulk
  • Parsing results (required for Get)

Tags: Java ElasticSearch search engine

Posted by vahidi on Fri, 03 Jun 2022 02:45:54 +0530