ElasticSearch uses RestHighLevelClient to search and query

Keywords: ElasticSearch Java Spring Apache

There are four types of client connection methods in the Elasticsearch Java API: TransportClient, RestClient, Jest, and spring [data] Elasticsearch. Among them, TransportClient and RestClient are the native api of Elasticsearch. TransportClient will be deleted in version 8.0, instead of HighLevelRestClient, which uses HTTP request instead of Java serialization request. Spring data elastic search is an elastic search development package integrated with spring. In the article "basic operation java version" of Elasticsearch 6.4 in blog Park, there is a simple description, not too many quotations. This article mainly records the use of high level RestClient in the spingboot project.

The use of es is mainly to do some non relational data document retrieval. The company uses the most is to cooperate with kibana for visual log retrieval, which is very convenient. elasticsearch, kibana installation, configuration and use, there are a lot of blog records, which will not be described here.

@Configuration configures spin and starts container @ Bean register Bean

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import java.util.ArrayList;
 
@Configuration
public class ESConfig {
 
    private static String hosts = "127.0.0.1"; // Cluster address, multiple use, separate
    private static int port = 9200; // Port number used
    private static String schema = "http"; // Protocol used
    private static ArrayList<HttpHost> hostList = null;
 
    private static int connectTimeOut = 1000; // Connection timeout
    private static int socketTimeOut = 30000; // Connection timeout
    private static int connectionRequestTimeOut = 500; // Get connection timeout
 
    private static int maxConnectNum = 100; // maximum connection
    private static int maxConnectPerRoute = 100; // Maximum number of routing connections
    static {
        hostList = new ArrayList<>();
        String[] hostStrs = hosts.split(",");
        for (String host : hostStrs) {
            hostList.add(new HttpHost(host, port, schema));
        }
    }
    @Bean
    public RestHighLevelClient client(){
        RestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0]));
        // Asynchronous httpclient connection delay configuration
        builder.setRequestConfigCallback(new RequestConfigCallback() {
            @Override
            public Builder customizeRequestConfig(Builder requestConfigBuilder) {
                requestConfigBuilder.setConnectTimeout(connectTimeOut);
                requestConfigBuilder.setSocketTimeout(socketTimeOut);
                requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
                return requestConfigBuilder;
            }
        });
        // Asynchronous httpclient connection number configuration
        builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                httpClientBuilder.setMaxConnTotal(maxConnectNum);
                httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
                return httpClientBuilder;
            }
        });
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }
}

Write a service.

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.io.IOException;
import java.util.Arrays;
 
@Service
public class ElasticSearchService {
    private static final Logger log = LoggerFactory.getLogger(ElasticSearchService.class);
 
    @Autowired
    private RestHighLevelClient client;
 
    public String search() throws IOException {
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("fields.entity_id", "319");//Here, you can search according to the fields. Most means qualified, while the opposite must not means unqualified
       // Rangequerybuilder rangequerybuilder = querybuilders.rangequery ("fields" timestamp "); / / create a new range condition
       // rangeQueryBuilder.gte("2019-03-21T08:24:37.873Z"); / / start time
       // rangeQueryBuilder.lte("2019-03-21T08:24:37.873Z"); / / end time
       // boolBuilder.must(rangeQueryBuilder);
        boolBuilder.must(matchQueryBuilder);
        sourceBuilder.query(boolBuilder); //Set query, which can be any type of QueryBuilder.
        sourceBuilder.from(0); //Set the from option to determine which index the results will be searched from. The default is 0
        sourceBuilder.size(100); //Set the size option to determine the number of search element hit returns. The default value is 10
      sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //Set an optional timeout to control the time allowed to search.


        sourceBuilder.fetchSource(new String[] {"fields.port","fields.entity_id","fields.message"}, new String[] {}); //The first is to get the fields, and the second is to filter the fields. All fields are obtained by default
        SearchRequest searchRequest = new SearchRequest("customer"); //Indexes
        searchRequest.types("doc"); //type
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();  //SearchHits provides global information about all matches, such as total hits or maximum scores:
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            log.info("search -> {}",hit.getSourceAsString());
        }
        return Arrays.toString(searchHits);
    }
}

The ElasticSearchService above has several commonly used Builder classes and methods that need to be understood.

BoolQueryBuilder is used to assemble query conditions. Generally speaking, the performance of must is lower, because it needs to be scored, that is to say, it needs to be scored, while the filter does not.

  • filter(QueryBuilder queryBuilder)

Adds a query that must appear in the matching documents but will not contribute to scoring.

  • must(QueryBuilder queryBuilder)
    Adds a query that must appear in the matching documents and will contribute to scoring.

  • should(QueryBuilder queryBuilder)
    Adds a query that should appear in the matching documents.

Simply put: must is equal to & =; must not is equal to non ~! =; should is equivalent to or; filter filtering

//filter efficiency is much higher than most 
 if (StringUtils.isNotBlank(query.getRouterDatabaseNo())) {
   boolQueryBuilder.filter(QueryBuilders.termQuery("routerDatabaseNo", query.getRouterDatabaseNo()));
 }

//The time period must have a head and a tail, or slow query will appear
 if (null != query.getCreateTime() && null != query.getUpdateTime()) {
     boolQueryBuilder.filter(QueryBuilders.rangeQuery("createTime").from( query.getCreateTime()).to(query.getUpdateTime()));
 }

SearchSourceBuilder

SearchRequest searchRequest = new SearchRequest("customer"); //Limit requests to one index
 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 searchRequest.types("doc"); //Limit the request to one type.
 searchRequest.source(sourceBuilder); //Add SearchSourceBuilder to SeachRequest

Create SeachRequest without parameters, which will run for all indexes. If there is a parameter, the value passed by the parameter is the index, where "customer" is the index value. Most of the search parameters are added to the SearchSourceBuilder, which provides a setter for everything in the search request body.

Sorting of SearchSourceBuilder: allows to add one or more SortBuilder instances, with four special implementations (Field -, Score -, GeoDistance -, and ScriptSortBuilder).

sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //Sort by "score descending" (default).
sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));//You can also sort the fields in ascending order

Source filtering of SearchSourceBuilder: by default, the search request will return the content of the document_source, but like the content in the Rest API, you can override this behavior. For example, you can turn off the search completely:

sourceBuilder.fetchSource(false);

The method also accepts an array of one or more wildcard patterns to control which fields are included or excluded in a more granular way

String[] includeFields = new String[] {"title", "user", "innerObject.*"};
String[] excludeFields = new String[] {"_type"};
sourceBuilder.fetchSource(includeFields, excludeFields);

Highlight request results of SearchSourceBuilder: highlight search results can be achieved by setting HighlightBuilder on SearchSourceBuilder, and different highlight behaviors can be defined for each field by adding one or more HighlightBuilder.Field instances to HighlightBuilder.

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder(); //Create a new HighlightBuilder.
HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title");  //Create a field highlight for the title field.
highlightTitle.highlighterType("unified"); // Sets the field highlight type.
highlightBuilder.field(highlightTitle);   //Adds a field highlight color to the highlight builder.
HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
highlightBuilder.field(highlightUser);
searchSourceBuilder.highlighter(highlightBuilder);

SearchSourceBuilder For more APIs, please refer to the link article, which is summarized in detail and no longer quoted too much.

Write a controller for testing

import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.slowcity.admin.service.ElasticSearchService;

@RestController 
@RequestMapping("/test")
public class TestResource {
    
    @Autowired
    private ElasticSearchService elasticSearchService;
    private static final Logger log = LoggerFactory.getLogger(TestResource.class);
    //Condition query 
    @PostMapping("/v1/test")
    public String query( ) {
        String queryResult =null;
        try {
            queryResult = elasticSearchService.search();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return queryResult;
    }
}

First, maintain several pieces of data in es, as follows:

The postman test results are as follows:

172 original articles published, 272 praised, 730000 visitors+
His message board follow

Posted by JOWP on Sat, 22 Feb 2020 19:20:16 -0800