download

  • accesshttps://www.elastic.co/cn/downloads/elasticsearch

The latest version at the time of writing is 7.8

  • Select a download mode as required

The installation

  • Decompression package
  • Go to the decompressed directory and run it./bin/elasticsearchEnable Elastic with port 9200 by default
  • Execute the commandcurl localhost:9200Request port Information Description The port is successfully started
$: curl localhost:9200
{
  "name" : "dfcdd082ff4b",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "qq-dpNhmTpu3pGhE10GJuA",
  "version" : {
    "number" : "7.8.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "757314695644ea9a1dc2fecd26d1a43856725e65",
    "build_date" : "2020-06-14T19:35:50.234439Z",
    "build_snapshot" : false,
    "lucene_version" : "8.5.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
Copy the code
  • Close Elastic and modify./config/elasticsearch.yml
  • willnetwork.hostRelease the comment and modify it to0.0.0.0 To allow anyone to access, the online environment must be set to a specific IP address

Installing a plug-in

Version Elastic Select the corresponding version

The default participle of ES is not friendly to Chinese. For example, when using the default participle of “epidemic disease”, the word “epidemic disease” will be divided into “epidemic disease” and “emotion” instead of “epidemic disease”. So you need to add a word Analyzer

  • Chinese word divider IK
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip
Copy the code
  • PINYIN word divider
bin/belasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip
Copy the code
  • Synonym plug-in

In learning, we can do semantic analysis through NLP, build thesaurus, and then find correlation through word segmentation

The basic concept

The Node and Cluster

Elastic is essentially a distributed database that allows multiple servers to work together and each server can run multiple Elastic instances.

A single Elastic instance is called a node. A group of nodes forms a cluster.

Index

The Elastic indexes all the fields, and after processing, writes a Inverted Index. When looking for data, look up the index directly.

So the top-level unit of Elastic data management is called an Index. It is a synonym for a single database. The name of each Index (that is, database) must be lowercase.

The following command displays all indexes of the current node.

$ curl -X GET 'http://localhost:9200/_cat/indices? v'
Copy the code

Document

The single record inside Index is called a Document. A number of documents form an Index.

Document is represented in JSON format, and here is an example.

{
  "user": "Zhang"."title": "Engineer"."desc": "Database Management"
}
Copy the code

Documents in the same Index are not required to have the same structure (scheme), but it is better to keep the same, so as to improve the search efficiency.

Type

Document can be grouped, for example, in the weather Index, it can be grouped by city (Beijing and Shanghai), or by climate (sunny and rainy days). This grouping is called Type, which is a virtual logical grouping used to filter documents.

Different types should have similar schemas. For example, an ID field cannot be a string in one group and a number in another. This is a difference from tables in a relational database. Data of completely different natures (such as products and logs) should be stored as two indexes instead of two Types in one Index (although that is possible).

The following command lists the types contained in each Index.

$ curl 'localhost:9200/_mapping? pretty=true'
Copy the code

As planned, Elastic 6.x will only allow one Type per Index and will remove Type entirely.

Spring integration

Transport uses TCP and restClient uses HTTP. However, transport will be removed in releases after 8

Therefore, you are advised to use it based on actual conditions

JavaAPI

The introduction of transport

<dependency>
	<groupId>org.elasticsearch.client</groupId>
	<artifactId>transport</artifactId>
	<version>${elasticsearch.version}</version>
</dependency>
Copy the code

Instantiate the TransportClient

Settings settings = Settings.builder()
	.put("cluster.name"."elasticsearch")
	.build();
TransportClient client = new PreBuiltTransportClient(settings);
/* * the TCP port on ES is 9300, instead of 9200
InetSocketTransportAddress node = new InetSocketTransportAddress(
InetAddress.getByName("localhost"),9300);
client.addTransportAddress(node);
Copy the code

Spring-Data-ElasticSearch

Introducing Spring – Data – ElasticSearch

The dependencies provided by Spring are based on Transport and the official recommendation is to use the Hight Level Rest Client

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-elasticsearch</artifactId>
</dependency>
Copy the code

Define the Document

@Document(indexName = "book")
class Book {
    @Id
    private Long id;

    @Field(searchAnalyzer = "ik_smart", analyzer = "ik_smart")
    private String name;
}
Copy the code
@Repository
public interface BookRepository extends ElasticsearchCrudRepository<Book.String> {}Copy the code

Enable scan for Repositories

@EnableElasticsearchRepositories(basePackages="xxx.xxx.xx")
Copy the code

Rest Client/ High-level Rest Client(recommended)

The introduction of RestHightLevelClient

RestHightLevelClient is an advanced wrapper based on RestClient

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>${elasticsearch.client.version}</version>
</dependency>
Copy the code

Configure the corresponding bean

/** * ElasticSearch config class * is triggered when a dependency is introduced and the context is not configured with RestClientBuilder@author shadow
 * @dateThe 2020-06-22 23:20:49 * /
@Configuration
@ConditionalOnClass(RestClientBuilder.class)
@ConditionalOnMissingBean(RestClientBuilder.class)
public class ElasticSearchAutoConfiguration {

    @Autowired
    private RestClientProperties restClientProperties;

    /**
     * RestClientBuilder
     * @return {@link RestClientBuilder}
     */
    @Bean
    public RestClientBuilder restClientBuilder(a) {
        List<String> urls = restClientProperties.getUris();
        List<HttpHost> httpHosts = new ArrayList<>(urls.size());
        for(String uri: urls) {
            httpHosts.add(HttpHost.create(uri));
        }
        return RestClient.builder(httpHosts.toArray(new HttpHost[urls.size()]));
    }

    /**
     * RestClient
     * @return {@link RestClient}
     */
    @Bean
    public RestClient restClient(a) {
        return restClientBuilder().build();
    }

    /**
     * RestHighLevelClient
     * @return {@link RestHighLevelClient}
     */
    @Bean
    public RestHighLevelClient restHighLevelClient(a) {
        return newRestHighLevelClient(restClientBuilder()); }}Copy the code

Create indexes

PUT /xxxxx
{
    "mappings": {
        "properties": {
            "id": {
                "type": "long"
            },
            "content": {
                "type": "text",
                "analyzer": "ik_smart"
            },
            "content": {
            		"type": "text",
            		"analyzer": "ik_max_word",
            		"search_analyzer": "ik_smart"
            }
        }
    },
    "settings": {
        "number_of_replicas": 0,
        "index": {
            "analysis.analyzer.default.type": "ik_max_word",
            "analysis.search_analyzer.default.type": "ik_smart"
        }
    }
}

Copy the code

Common operations

The following are written using a High-level Rest Client

Create indexes

CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
return restHighLevelClient.indices()
	.create(createIndexRequest, RequestOptions.DEFAULT)
	.index();
Copy the code

Increase the data

You are advised to assign an independent ID to each data to facilitate subsequent operations

IndexRequest indexRequest = new IndexRequest(index);
indexRequest.id(source.getId());
indexRequest.source(source); // {"id": "123456", "content": "xxxxxx"}
Copy the code

Update the data

IndexRequest indexRequest = new IndexRequest(index);
indexRequest.id(source.getId();
indexRequest.source(source);// {"id": "123456", "content": "yyyyyyy"}
Copy the code

Delete the data

DeleteRequest deleteRequest = new DeleteRequest(index);
deleteRequest.id(id);
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
Copy the code

Query data

TermQuery

Fuzzy query, complete matching input.

Similar to regular /x/g

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery(field, value));
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Copy the code

MatchQuery

The difference between fuzzy query, simple description and term is that the input will be segmented, such as Chinese word segmentation and synonyms introduced above. Macth is a partially matched fuzzy query, which is relatively loose

Similar to the regular /. * (x | y). * / g

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery(field, value));
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Copy the code

MatchPhraseQuery

As with MatchQuery, the input is segmented, but the result must also contain all the participles in the same order

Similar to the canonical /.*x.*y.*z/g, and the result is also checked

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchPhraseQuery(field, value));
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Copy the code

QueryStringQuery

Similar to match, but without specifying attributes. Will search all fields, a wider range

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.queryStringQuery(value));
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Copy the code

BoolQuery

The and or not query corresponds to Lucene’s BooleanQuery

Similar to the regular /. * (a | b) ((c) (d) | e). * / g

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// Add a condition
boolQueryBuilder.must().add(QueryBuilders.matchQuery(key, value));
boolQueryBuilder.should().add(QueryBuilders.matchQuery(key, value));

sourceBuilder.query(boolQueryBuilder);
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Copy the code

Remove the index

Note that when an index is deleted, all data under the index is erased

DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
Copy the code

The interface definition

Interface class

/** * Search service interface **@param<E> Implements class generics *@author shadow
 * @version 0.0.1
 * @dateThe 2020-02-21 *@since0.0.1 * /
public interface SearchService<E> {

    /** * Whether the index exists **@paramThe index index *@return true/false
     * @throws IOException IO
     */
    boolean exists(String index) throws IOException;

    /** * Whether the index exists **@paramIndices multiindex *@return true/false
     * @throws IOException IO
     */
    boolean exists(String... indices) throws IOException;

    /** * index **@paramThe index index *@returnThe index *@throws IOException IO
     */
    String index(String index) throws IOException;

    /** * index **@paramThe index index *@param mappingPath {@linkCom. Hephaestus. Search. Configuration. ElasticSearchMappingConfig: prefix} splicing *@returnThe index *@throws IOException IO
     */
    String index(String index, String mappingPath) throws IOException;

    /** * multiple indexes **@paramIndices multiindex *@returnThe index set of *@throws IOException IO
     */
    String[] index(String... indices) throws IOException;

    /** * Add document **@paramThe index index *@paramThe source source *@returnThe index *@throws IOException IO
     */
    String document(String index, Object source) throws IOException;

    /** * Add document **@paramIndices multiindex *@returnThe index set of *@throws IOException IO
     */
    String[] document(Map<String, BaseEntity> indices) throws IOException;

    /** * drop index **@paramThe index index *@return true/false
     * @throws IOException IO
     */
    Boolean delete(String index) throws IOException;

    /** * delete multiple indexes **@paramIndices multiindex *@return true/false
     * @throws IOException IO
     */
    Boolean delete(String... indices) throws IOException;

    /** * delete **@paramThe index index *@param id    id
     * @return true/false
     * @throws IOException IO
     */
    Boolean delete(String index, String id) throws IOException;

    /** * conditional delete **@paramThe index index *@paramKey property name *@paramValue Indicates the attribute value *@returnNumber of deletions *@throws IOException IO
     */
    Long queryDelete(String index, String key, String value) throws IOException;

    /** * search for **@paramThe index index *@paramField property name *@paramThe value value *@return {@link SearchHit }
     * @throws IOException IO
     */
    SearchHit[] search(String index, String field, String value) throws IOException;

    /** * search for **@paramThe index index *@paramOption condition object *@return {@link SearchHit }
     * @throws IOException IO
     */
    SearchHit[] search(String index, Object option) throws IOException;

    /** * search for **@paramThe index subscript *@paramOptions multi-conditional array *@return {@link SearchHit }
     * @throws IOException IO
     */
    SearchHit[] search(String index, Object[] options) throws IOException;

    /** * search - by index **@paramThe index index *@paramField property name *@paramThe value value *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> searchByIndex(String index, String field, String value) throws IOException {
        SearchHit[] hits = search(index, field, value);
        return toList(hits);
    }

    /** * search - by index **@paramThe index index *@paramOption condition object *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> searchByIndex(String index, Object option) throws IOException {
        SearchHit[] hits = search(index, option);
        return toList(hits);
    }

    /** * search - by index **@paramThe index index *@paramOptions Condition group *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> searchByIndex(String index, Object[] options) throws IOException {
        SearchHit[] hits = search(index, options);
        return toList(hits);
    }

    /** * search for **@paramField property name *@paramThe value value *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> search(String field, String value) throws IOException {
        return searchByIndex(null, field, value);
    }

    /** * search for **@paramOption condition object *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> search(Object option) throws IOException {
        return searchByIndex(null, option);
    }

    /** * search for **@paramOptions Condition group *@return {@link List<String>}
     * @throws IOException IO
     */
    default List<String> search(Object[] options) throws IOException {
        return toList(search(null, options));
    }

    /** * search for **@paramOptions Condition group *@paramClazz class *@param< T > generic *@return {@link List<T>}
     * @throws IOException IO
     */
    default <T> List<T> search(Object[] options, Class<T> clazz) throws IOException {
        return toList(search(options), clazz);
    }

    /** * search for **@paramThe index index *@paramOptions Condition group *@paramClazz class *@param< T > generic *@return {@link List<T>}
     * @throws IOException IO
     */
    default <T> List<T> search(String index, Object[] options, Class<T> clazz) throws IOException {
        return toList(searchByIndex(index, options), clazz);
    }

    /** * search for **@paramOption condition object *@paramClazz class *@param< T > generic *@return {@link List<T>}
     * @throws IOException IO
     */
    default <T> List<T> search(Object option, Class<T> clazz) throws IOException {
        return toList(searchByIndex(null, option), clazz);
    }

    /** * search for **@paramField property name *@paramThe value value *@paramClazz class *@param< T > generic *@return {@link List<T>}
     * @throws IOException IO
     */
    default <T> List<T> search(String field, String value, Class<T> clazz) throws IOException {
        List<String> hits = search(field, value);
        return toList(hits, clazz);
    }

    /** * search for **@paramThe index index *@paramField property name *@paramThe value value *@paramClazz class *@param< T > generic *@return {@link List<T>}
     * @throws IOException IO
     */
    default <T> List<T> search(String index, String field, String value, Class<T> clazz) throws IOException {
        List<String> hits = searchByIndex(index, field, value);
        return toList(hits, clazz);
    }

    /** * to List **@param hits {@link List<SearchHit>}
     * @return {@linkList<String>} JSON String */
    default List<String> toList(SearchHit[] hits) {
        List<String> results = new ArrayList<>(hits.length);
        Arrays.stream(hits).forEach(hit -> results.add(hit.getSourceAsString()));
        return results;
    }

    /** * to List **@param hits  {@link List<SearchHit>}
     * @paramClazz class *@param< T > generic *@return {@linkList<T>} Generic conversions */
    default <T> List<T> toList(List<String> hits, Class<T> clazz) {
        List<T> results = new ArrayList<>(hits.size());
        hits.forEach(hit -> results.add(JsonUtils.toObject(hit, clazz)));
        return results;
    }


    /** * get the search instance **@return<E> Implementation class */
    E getOrigin(a);
}

Copy the code

Interface implementation

/** * Search service implementation class * based on ElasticSearch RestHighLevelClient implementation **@author shadow
 * @version 0.0.1
 * @dateThe 2020-02-21 *@since0.0.1 * * <p> * Suppress ali-P3C specification without ending with IMPL */
@SuppressWarnings("AlibabaServiceOrDaoClassShouldEndWithImpl")
@Service
public class ElasticSearchService implements SearchService<RestHighLevelClient> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchService.class);

    /** Default ID attribute */
    private static final String FIELD_ID = "id";
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private ElasticSearchMappingConfig elasticSearchMappingConfig;

    /** * Whether the index exists **@paramThe index index *@return true/false
     */
    @Override
    public boolean exists(String index) throws IOException {
        return exists(new String[]{index});
    }

    /** * Whether the index exists **@paramIndices multiindex *@return true/false
     * @throws IOException IO
     */
    @Override
    public boolean exists(String... indices) throws IOException {
        GetIndexRequest getIndexRequest = new GetIndexRequest(indices);
        return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
    }

    /** * index **@paramThe index index *@returnThe index *@throws IOException IO
     */
    @Override
    public String index(String index) throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
        return restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT).index();
    }

    /** * index **@paramThe index index *@param mappingPath {@linkElasticSearchMappingConfig: prefix} splicing *@returnThe index *@throws IOException IO
     */
    @Override
    public String index(String index, String mappingPath) throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
        File resource = ResourceUtils.getFile(elasticSearchMappingConfig.getPrefix() + mappingPath);
        String source = JSONUtil.readJSON(resource, StandardCharsets.UTF_8).toStringPretty();
        createIndexRequest.source(source, XContentType.JSON);
        return restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT).index();
    }

    /** * multiple indexes **@paramIndices multiindex *@returnThe index set of *@throws IOException IO
     */
    @Override
    public String[] index(String... indices) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        Arrays.stream(indices).forEach(index -> {
            IndexRequest indexRequest = new IndexRequest(index);
            bulkRequest.add(indexRequest);
        });
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        List<String> result = new ArrayList<>(indices.length);
        Arrays.stream(bulkResponse.getItems()).forEach(response -> result.add(response.getIndex()));
        return result.toArray(new String[indices.length]);
    }

    /** * Add document **@paramThe index index *@paramThe source source *@returnThe index *@throws IOException 1
     */
    @Override
    public String document(String index, Object source) throws IOException {
        IndexRequest indexRequest = new IndexRequest(index);
        Object id = BeanUtil.getProperty(source, FIELD_ID);
        if(id ! =null) {
            indexRequest.id(id.toString());
        }
        indexRequest.source(BeanUtil.beanToMap(source));
        return restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT).getIndex();
    }

    /** * Add document **@paramIndices multiindex *@returnThe index set of *@throws IOException IO
     */
    @Override
    public String[] document(Map<String, BaseEntity> indices) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        indices.forEach((index, value) -> {
            IndexRequest indexRequest = new IndexRequest(index);
            indexRequest.source(value);
            indexRequest.id(BeanUtil.getProperty(value, FIELD_ID).toString());
            bulkRequest.add(indexRequest);
        });
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        List<String> result = new ArrayList<>(indices.size());
        Arrays.stream(bulkResponse.getItems()).forEach(response -> result.add(response.getIndex()));
        return result.toArray(new String[indices.size()]);
    }

    /** * delete **@paramThe index index *@param id    id
     * @return true/false
     * @throws IOException IO
     */
    @Override
    public Boolean delete(String index, String id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(index);
        deleteRequest.id(id);
        DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        return deleteResponse.getId().equals(id);
    }

    /** * drop index **@paramThe index index *@return true/false
     * @throws IOException IO
     */
    @Override
    public Boolean delete(String index) throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        return acknowledgedResponse.isAcknowledged();
    }

    / * * *@paramIndices multiindex *@return true/false
     * @throws IOException IO
     */
    @Override
    public Boolean delete(String... indices) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        for (String index : indices) {
            DeleteRequest deleteRequest = new DeleteRequest(index);
            bulkRequest.add(deleteRequest);
        }
        BulkResponse bulkItemResponses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return bulkItemResponses.hasFailures();
    }

    /** * conditional delete **@paramThe index index *@paramKey property name *@paramValue Indicates the attribute value *@returnNumber of deletions *@throws IOException IO
     */
    @Override
    public Long queryDelete(String index, String key, String value) throws IOException {
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index);
        deleteByQueryRequest.setQuery(new TermQueryBuilder(key, value));
        BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
        return bulkByScrollResponse.getTotal();
    }

    /** * search for **@paramThe index index *@paramField property name *@paramThe value value *@return {@link SearchHit }
     * @throws IOException IO
     */
    @Override
    public SearchHit[] search(String index, String field, String value) throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery(field, value));
        SearchRequest searchRequest = index == null ? new SearchRequest() : new SearchRequest(index);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        return searchResponse.getHits().getHits();
    }

    /** * search for **@paramThe index index *@paramOption condition object *@return {@link SearchHit }
     * @throws IOException IO
     */
    @Override
    public SearchHit[] search(String index, Object option) throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        BeanUtil.beanToMap(option).forEach((key, value) -> {
            if(value ! =null) { boolQueryBuilder.must().add(QueryBuilders.matchQuery(key, value)); }}); sourceBuilder.query(boolQueryBuilder); SearchRequest searchRequest = index ==null ? new SearchRequest() : new SearchRequest(index);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        return searchResponse.getHits().getHits();
    }

    /** * search *@paramThe index subscript *@paramOptions multi-conditional array *@return {@link SearchHit }
     * @throws IOException IO
     */
    @Override
    public SearchHit[] search(String index, Object[] options) throws IOException{
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // Array forEach loop, then convert the object to Map,null value skipped
        Arrays.stream(options).forEach(option -> BeanUtil.beanToMap(option).forEach((key, value) -> {
            if(value ! =null) { boolQueryBuilder.must().add(QueryBuilders.matchQuery(key, value)); }})); sourceBuilder.query(boolQueryBuilder); SearchRequest searchRequest = index ==null ? new SearchRequest() : new SearchRequest(index);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        return searchResponse.getHits().getHits();
    }
    /** * get the search instance **@returnT Search for instance */
    @Override
    public RestHighLevelClient getOrigin(a) {
        returnrestHighLevelClient; }}Copy the code

Visualization tool

Elastic HD

Download address

reference

Chinese document

The Chinese version is based on ElasticSearch2.x. Some content may be outdated. You are advised to read the latest version

Elastic Product Documentation

Full text Search Engine Elasticsearch tutorial