• ElasticSearch(九)【SpringBoot整合】


    九、SpringBoot整合Elasticsearch


    上一篇文章ElasticSearch - 过滤查询

    9.1 基本环境配置

    1. 创建一个springboot工程springboot-elasticsearch
    2. pom.xml导入依赖
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-elasticsearchartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    注意】使用的springboot需要根当前ES版本兼容

    在这里插入图片描述

    1. 配置application.yml文件
    # 应用名称
    spring:
      application:
        name: springboot-elasticsearch
    # web端口号
    server:
      port: 3035
    # 自定义es主机和端口号:
    es:
      host: 192.168.159.100:9200
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 配置客户端

    创建config包,添加配置类RestClientConfiguration.class

    package com.vinjcent.config;
    
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.client.ClientConfiguration;
    import org.springframework.data.elasticsearch.client.RestClients;
    import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
    
    // ES 配置类
    @Configuration
    public class RestClientConfiguration extends AbstractElasticsearchConfiguration {
    
        @Value("${es.host}")
        private String host;
    
        @Bean
        @Override   // ES 两个端口,一个是9200(rest方式通信),一个是9300(tcp方式通信)
        public RestHighLevelClient elasticsearchClient() {
            final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo(host)
                    .build();
            return RestClients.create(clientConfiguration).rest();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    配置完之后,该配置类不仅会创建RestHighLevelClient的bean,还会帮我们创建一个叫做ElasticsearchOperations客户端对象

    为什么要提供这两个对象呢?

    因为Spring Data在封装ES操作的时候,完全站在了两个角度去考虑

    • ElasticsearchOperations这个bean在操作ES的时候,主要以对象作为基础去操作,ElasticsearchOperations序列化对象之后传递给ES,ES在查询到结果之后,反序列化传递给ElasticsearchOperations
    • RestHighLevelClient更像于可视化的Kibana,通过rest的方式与ES进行交互(企业多用,推荐使用)

    9.2 ElasticsearchOperations

    • 特点:始终使用面向对象方式操作ES
      • 索引:用来存放相似文档的集合
      • 映射:用来决定放入文档的每个字段以什么样方式录入到ES中,字段类型、字段分词器…
      • 文档:可以被索引最小单元,json数据格式

    使用ElasticsearchOperations进行增删查改操作

    1. 创建一个Product实体类
    package com.vinjcent.pojo;
    
    
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldType;
    
    import java.io.Serializable;
    
    /**
     * @Document: 将这个类对象转为 es 中一条文档进行录入
     * indexName: 用来指定文档的索引名称
     * createIndex: 用来指定是否创建索引,默认为false
     */
    @Document(indexName = "products", createIndex = true)
    public class Product implements Serializable {
    
        @Id // 用来将放入对象id值作为文档_id进行映射
        private Integer id;
    
        @Field(type = FieldType.Keyword)    // 字段映射类型
        private  String title;
    
        @Field(type = FieldType.Double)
        private Double price;
    
        @Field(type = FieldType.Text)
        private String description;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public Double getPrice() {
            return price;
        }
    
        public void setPrice(Double price) {
            this.price = price;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        @Override
        public String toString() {
            return "Product{" +
                    "id=" + id +
                    ", title='" + title + '\'' +
                    ", price=" + price +
                    ", description='" + description + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    1. 在使用SpringBoot操作之前,将索引记录删除
    # 查询索引
    GET /_cat/indices?v
    
    # 删除索引
    DELETE /product
    
    # 查看索引映射
    GET /products/_mapping
    
    # 查看数据
    GET /products/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 使用Java操作ES进行增、删、查、改、
    package com.vinjcent;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.vinjcent.pojo.Product;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
    import org.springframework.data.elasticsearch.core.SearchHit;
    import org.springframework.data.elasticsearch.core.SearchHits;
    import org.springframework.data.elasticsearch.core.query.Query;
    
    @SpringBootTest
    public class ElasticSearchOperationsTest{
    
        private final ElasticsearchOperations elasticsearchOperations;
    
        @Autowired
        public ElasticSearchOperationsTest(ElasticsearchOperations elasticsearchOperations) {
            this.elasticsearchOperations = elasticsearchOperations;
        }
    
        /**
         * save 索引一条文档 或 更新一条文档
         * save 方法当文档id不存在时添加文档,当文档id存在时候更新文档
         */
        @Test
        public void testSave() {
            Product product = new Product();
            product.setId(1);
            product.setPrice(2.5);
            product.setTitle("vinjcent的妙妙屋");
            product.setDescription("真是米奇妙妙屋,妙到了家");
            elasticsearchOperations.save(product);
        }
    
        /**
         * query 根据id查询一条文档
         */
        @Test
        public void testQuery() {
            Product product = elasticsearchOperations.get("1", Product.class);
            System.out.println(product);
        }
    
        /**
         * delete 根据id删除一条文档
         */
        @Test
        public void testDelete() {
            Product product = new Product();
            product.setId(1);
            String delete = elasticsearchOperations.delete(product);
            System.out.println(delete);
        }
    
        /**
         * delete 删除所有
         */
        @Test
        public void testDeleteAll() {
            elasticsearchOperations.delete(Query.findAll(), Product.class);
        }
    
        /**
         * 查询所有
         */
        @Test
        public void testQueryAll() throws JsonProcessingException {
            SearchHits<Product> productSearchHits = elasticsearchOperations.search(Query.findAll(), Product.class);
            System.out.println("总分数: " + productSearchHits.getMaxScore());
            System.out.println("符合条件总数: " + productSearchHits.getTotalHits());
            for (SearchHit<Product> productSearchHit : productSearchHits) {
                System.out.println(new ObjectMapper().writeValueAsString(productSearchHit.getContent()));
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    9.3 RestHighLevelClient

    使用RestHighLevelClient进行索引操作

    1. 在使用SpringBoot操作之前,将索引记录删除
    # 查询索引
    GET /_cat/indices?v
    
    # 删除索引
    DELETE /products
    
    # 查看数据
    GET /products/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 测试类RestHighLevelClientTests.class
    package com.vinjcent;
    
    import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    import org.elasticsearch.action.support.master.AcknowledgedResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.client.indices.CreateIndexRequest;
    import org.elasticsearch.client.indices.CreateIndexResponse;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    
    @SpringBootTest
    public class RestHighLevelClientTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
        /**
         * 创建索引、映射
         */
        @Test
        public void testIndexAndMapping() throws IOException {
    
            // 1.创建索引请求对象
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("products");
            // 2.指定映射,参数1: 指定映射json结构     参数2: 指定映射类型
            createIndexRequest.mapping("{\n" +
                    "    \"properties\": {\n" +
                    "      \"title\": {\n" +
                    "        \"type\": \"keyword\"\n" +
                    "      },\n" +
                    "      \"price\": {\n" +
                    "        \"type\": \"double\"\n" +
                    "      },\n" +
                    "      \"create_time\": {\n" +
                    "        \"type\": \"date\"\n" +
                    "      },\n" +
                    "      \"description\": {\n" +
                    "        \"type\": \"text\", \n" +
                    "        \"analyzer\": \"ik_max_word\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  }", XContentType.JSON);
    
            // 参数1: 创建索引请求对象    参数2: 请求配置对象
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            System.out.println("创建状态: " + createIndexResponse.isAcknowledged());
    
            restHighLevelClient.close();    // 关闭资源
        }
    
        /**
         * 删除索引
         * @throws IOException
         */
        @Test
        public void testDeleteIndex() throws IOException {
            // 参数1: 创建索引请求对象    参数2: 请求配置对象
            AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(new DeleteIndexRequest("products"), RequestOptions.DEFAULT);
            System.out.println(acknowledgedResponse.isAcknowledged());
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    在这里插入图片描述

    在这里插入图片描述

    使用RestHighLevelClient进文档操作

    package com.vinjcent;
    
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.delete.DeleteResponse;
    import org.elasticsearch.action.get.GetRequest;
    import org.elasticsearch.action.get.GetResponse;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    import org.elasticsearch.action.update.UpdateRequest;
    import org.elasticsearch.action.update.UpdateResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    
    @SpringBootTest
    public class RestHighLevelClientForDocumentTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientForDocumentTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
        /**
         * 创建一条文档
         * @throws IOException
         */
        @Test
        public void testCreateDocu() throws IOException {
            // 1.创建索引对象
            IndexRequest indexRequest = new IndexRequest("products");
            // 2.配置创建的文档对象
            indexRequest.id("1")    // 手动指定文档的id
                    .source("{\n" +     // 文档的数据内容
                    "  \"title\": \"vinjcent米奇妙妙屋\",\n" +
                    "  \"price\": 21.5,\n" +
                    "  \"create_time\": \"2022-09-16\",\n" +
                    "  \"description\": \"真是妙到家了!\"\n" +
                    "}",XContentType.JSON);
            // 3.接收请求后的索引响应对象,参数1: 索引请求对象  参数2: 请求配置对象
            IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    
            System.out.println(indexResponse.status());
        }
    
        /**
         * 更新一条文档
         * @throws IOException
         */
        @Test
        public void testUpdateDocu() throws IOException {
    
            // 1.创建更新请求对象
            UpdateRequest updateRequest = new UpdateRequest("products", "2");
    
            // 2.配置doc文档对象
            updateRequest.doc("{\n" +
                    "    \"title\": \"totoro--的米奇妙妙屋\"\n" +
                    "  }", XContentType.JSON);
    
            // 参数1: 更新请求对象  参数2: 请求配置对象
            UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    
            System.out.println(updateResponse.status());
        }
    
        /**
         * 删除一条文档
         * @throws IOException
         */
        @Test
        public void testDeleteDocu() throws IOException {
    
            // 参数1: 更新请求对象  参数2: 请求配置对象
            DeleteResponse deleteResponse = restHighLevelClient.delete(new DeleteRequest("products", "2"), RequestOptions.DEFAULT);
            System.out.println(deleteResponse.status());
        }
    
        /**
         * 基于id查询一条文档
         * @throws IOException
         */
        @Test
        public void testQueryByIdDocu() throws IOException {
    	    // 1.声明get请求对象
            GetRequest getRequest = new GetRequest("products", "1");
            // 2.接收响应对象		参数1: 获取请求对象  参数2: 请求配置对象
            GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
    
            System.out.println("id: " + getResponse.getId());
    
            System.out.println("source: " + getResponse.getSourceAsString());
    
    
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    9.4 RestHighLevelClient 查询操作

    package com.vinjcent;
    
    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.QueryBuilder;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    
    @SpringBootTest
    public class RestHighLevelClientForDocumentTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientForDocumentTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
        /**
         * 查询所有
         */
        @Test
        public void testMatchAll() throws IOException {
            // 1.搜索请求对象
            SearchRequest searchRequest = new SearchRequest("products");
    
            // 2.指定条件对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
            // 3.配置请求对象中的条件对象
            searchSourceBuilder.query(QueryBuilders.matchAllQuery());  // 查询所有
            searchRequest.source(searchSourceBuilder);
    
            // 参数1: 搜索的请求对象     参数2: 请求配置对象     返回值: 擦汗寻结果对象
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("总条数: " + searchResponse.getHits().getTotalHits().value);
            System.out.println("最大得分: " + searchResponse.getHits().getMaxScore());
    
            // 获取结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            for (SearchHit hit : hits) {
                String id = hit.getId();
                System.out.println("source: " + hit.getSourceAsString());
            }
        }
    
        /**
         * 关键字查询 term
         */
        @Test
        public void testTerm() throws IOException {
            query(QueryBuilders.termQuery("description","真是"));
        }
    
        /**
         * 范围查询 range
         */
        @Test
        public void testRange() throws IOException {
            query(QueryBuilders.rangeQuery("price").gt(0).lt(50));
        }
    
        /**
         * 前缀查询 prefix
         */
        @Test
        public void testPrefix() throws IOException {
            query(QueryBuilders.prefixQuery("title", "vinjcent"));
        }
    
        /**
         * 通配符查询 wildcard
         */
        @Test
        public void testWildcard() throws IOException {
            // "*"代表多个字符,"?"代表一个字符
            query(QueryBuilders.wildcardQuery("title", "vinjcent*"));
        }
    
        /**
         * 多id查询 ids
         */
        @Test
        public void testIds() throws IOException {
            // "*"代表多个字符,"?"代表一个字符
            query(QueryBuilders.idsQuery().addIds("1","2"));
        }
    
        /**
         * 多字段查询 multi_match
         */
        @Test
        public void testMultiMatch() throws IOException {
            // 如果查的字段分词,会先进行分词处理,否则不进行分词处理
            query(QueryBuilders.multiMatchQuery("妙", "title","description"));
        }
    
    
        public void query(QueryBuilder queryBuilder) throws IOException {
    
            // 1.搜索请求对象
            SearchRequest searchRequest = new SearchRequest("products");
    
            // 2.指定条件对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
            // 3.配置请求对象中的条件对象
            searchSourceBuilder.query(queryBuilder);  // 关键字
            searchRequest.source(searchSourceBuilder);
    
            // 参数1: 搜索的请求对象     参数2: 请求配置对象     返回值: 擦汗寻结果对象
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("总条数: " + searchResponse.getHits().getTotalHits().value);
            System.out.println("最大得分: " + searchResponse.getHits().getMaxScore());
    
            // 获取结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("id: " + hit.getId() + " source: " + hit.getSourceAsString());
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133

    9.5 RestHighLevelClient 高亮、分页、排序

    package com.vinjcent;
    
    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.QueryBuilder;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
    import org.elasticsearch.search.sort.SortOrder;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    import java.util.Map;
    
    @SpringBootTest
    public class RestHighLevelClientForDocumentTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientForDocumentTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
    
        /**
         * 分页查询     from 起始位置   size 分页大小
         * 排序查询     sort
         * 指定字段获取   _source
         * 高亮查询     highlight
         * @throws IOException
         */
        @Test
        public void testSearch() throws IOException {
    
            // 1.创建请求索引对象
            SearchRequest searchRequest = new SearchRequest("products");
            // 2.创建搜索条件对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            // 3.创建高亮对象
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.requireFieldMatch(false)   // 注意: 开启高亮的字段必须可以分词,不然查询结果无效
                    .preTags("")  // 配置高亮包裹前缀
                    .postTags("")                    // 配置高亮包裹后缀
                    .field("description")                   // 指定高亮字段
                    .field("title");                        // 指定高亮字段
            searchSourceBuilder.query(QueryBuilders.termQuery("description", "妙"))
                                .from(0)    // 起始位置
                                .size(2)    // 分页大小,默认返回是10条
                                .sort("price", SortOrder.DESC) // 指定排序字段以及排序方式
                                .fetchSource(null, new String[]{"create_time"})  // 参数1: 包含字段数组  参数2: 排除字段数组  注意,当两者结合使用时,只有前者会生效
                                .highlighter(highlightBuilder);
            // 4.为请求对象配置搜素对象
            searchRequest.source(searchSourceBuilder);
            // 5.接收响应对象
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("总条数: " + searchResponse.getHits().getTotalHits().value);
            System.out.println("最大得分: " + searchResponse.getHits().getMaxScore());
    
            // 获取结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("id: " + hit.getId() + " source: " + hit.getSourceAsString());
                // 获取高亮字段description
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields.containsKey("description")) {
                    System.out.println("description高亮结果: " + highlightFields.get("description").fragments()[0]);    // 获取的字段为数组形式
                }
                // 获取高亮字段title
                if (highlightFields.containsKey("title")) {
                    System.out.println("title高亮结果: " + highlightFields.get("title").fragments()[0]);    // 获取的字段为数组形式
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    9.6 RestHighLevelClient 过滤查询

    package com.vinjcent;
    
    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.QueryBuilder;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
    import org.elasticsearch.search.sort.SortOrder;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    import java.util.Map;
    
    @SpringBootTest
    public class RestHighLevelClientForDocumentTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientForDocumentTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
    
        /**
         * query    精确查询,查询计算文档得分,并根据文档得分进行返回
         * filter query   过滤查询,用来在大量数据中筛选出本地查询相关数据,不会计算文档得分,会对数据进行缓存
         * 注意: 当两种查询一起使用时,ES优先执行filter query,后执行query
         */
        @Test
        public void testFilterQuery() throws IOException {
    
            // 1.创建请求索引对象
            SearchRequest searchRequest = new SearchRequest("products");
            // 2.创建搜索条件对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            // 3.配置查询条件
            searchSourceBuilder
                    .query(QueryBuilders.matchAllQuery())
                    // ids、exists、term、terms、range等等都可以修改
                    .postFilter(QueryBuilders.termQuery("description", "妙"));
    
            // 4.为请求对象配置搜素对象
            searchRequest.source(searchSourceBuilder);
            // 5.接收响应对象
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("总条数: " + searchResponse.getHits().getTotalHits().value);
            System.out.println("最大得分: " + searchResponse.getHits().getMaxScore());
    
            // 获取结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("id: " + hit.getId() + " source: " + hit.getSourceAsString());
            }
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    9.7 RestHighLevelClient 应用使用JSON

    package com.vinjcent;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.vinjcent.pojo.Product;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    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.common.xcontent.XContentType;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    @SpringBootTest
    public class RestHighLevelClientForDocumentTests {
    
        private final RestHighLevelClient restHighLevelClient;
    
        @Autowired
        public RestHighLevelClientForDocumentTests(@Qualifier("elasticsearchClient") RestHighLevelClient restHighLevelClient) {
            this.restHighLevelClient = restHighLevelClient;
        }
    
    
        /**
         * 在有索引映射的条件下
         * 将对象放入ES中,进行序列化操作
         */
        @Test
        public void testAddDoc() throws IOException {
            Product product = new Product();
            product.setId(2);
            product.setPrice(5.2);
            product.setTitle("vinjcent米奇妙妙屋");
            product.setDescription("我的心可不冷");
    
            IndexRequest indexRequest = new IndexRequest("products");
            indexRequest.id(product.getId().toString())
                    .source(new ObjectMapper().writeValueAsString(product), XContentType.JSON); // 使用spring中自带的json对象转换
            IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
            System.out.println(indexResponse.status());
        }
    
        /**
         * 将对象从ES中读取,进行反序列化
         */
        @Test
        public void testGetDoc() throws IOException {
            // 1.创建请求对象
            SearchRequest searchRequest = new SearchRequest("products");
    
            // 2.创建搜索条件对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            // 3. 高亮对象
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder
                    .requireFieldMatch(false)
                    .field("description")
                    .preTags("")
                    .postTags("");
            // 4.指定查询条件
            searchSourceBuilder
                    .query(QueryBuilders.termQuery("description", "绝境"))
                    .from(0)
                    .size(10)
                    .highlighter(highlightBuilder);
            // 5.为请求对象配置条件对象
            searchRequest.source(searchSourceBuilder);
            // 6.接收响应对象
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("总条数: " + searchResponse.getHits().getTotalHits().value);
            System.out.println("最大得分: " + searchResponse.getHits().getMaxScore());
    
            List<Product> products = new ArrayList<>();
            // 获取响应结果对象
            SearchHit[] hits = searchResponse.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println(hit.getSourceAsString());    // json格式
                Product product = new ObjectMapper().readValue(hit.getSourceAsString(), Product.class); // 将json转为Product对象
    
                // 处理高亮
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields.containsKey("description")) {
                    // 获取高亮后的属性值,进行修改
                    product.setDescription(highlightFields.get("description").fragments()[0].toString());
                }
    
                products.add(product);
    
            }
    
            for (Product product : products) {
                System.out.println(product);
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112

    下一篇文章ElasticSearch - 聚合查询

  • 相关阅读:
    H3C(华三)交换堆叠/IRF配置实例
    DO LARGE LANGUAGE MODELS KNOW ABOUT FACTS?
    Unity的IPreprocessShaders:深入解析与实用案例
    linux rsyslog安装配置
    科学计算三维可视化笔记(第五周 交互界面)
    2022-9-16 第七小组 学习日记 (day71)Maven
    【EC200U】 基站定位
    一文带你上手自动化测试中的PO模式!
    汽车虚拟仿真视频数据理解--CLIP模型原理
    Hadoop 集群的安装与配置
  • 原文地址:https://blog.csdn.net/Wei_Naijia/article/details/126923817