• ElasticSearch--整合SpringBoot


    引入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4

    配置客户端

    @Configuration
    public class RestClientConfig extends AbstractElasticsearchConfiguration {
        @Override
        @Bean
        public RestHighLevelClient elasticsearchClient() {
            final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo("172.16.91.10:9200")
                    .build();
            return RestClients.create(clientConfiguration).rest();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    SpringBoot提供了两种操作ES的客户端

    • RestHighLevelClient 推荐

    ElasticsearchOperations

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

    相关注解

    • @Document(indexName=“products”, createIndex=true) 用在类上,表示为一个ES中的文档
      • indexName属性:创建索引的名称
      • createIndex属性:是否创建索引
    • @Id 标记在属性上,将对象的 id 字段映射成文档中的 _id
    • @Field(type=FieldTpye.keyword) :表示索引中字段的类型
      • type:指定字段类型
    @Document(indexName = "product", createIndex = true)
    public class Product {
        @Id
        private Integer id;
        @Field(type = FieldType.Keyword)
        private String title;
        @Field(type = FieldType.Float)
        private Double price;
        @Field(type = FieldType.Text)
        private String description;
        //get set ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    基本操作

    public class ElasticSearchOptionsTest extends ElasticsearchApplicationTests{
    
        private ElasticsearchOperations elasticsearchOperations;
    
        @Autowired
        public ElasticSearchOptionsTest(ElasticsearchOperations elasticsearchOperations){
            this.elasticsearchOperations=elasticsearchOperations;
        }
    
    
        /**
         * save:当文档id不存在时,新增文档;如果存在就修改文档
         */
        @Test
        public void testIndex(){
            Product product=new Product();
            product.setId(1);
            product.setTitle("小浣熊干脆面");
            product.setPrice(5.5);
            product.setDescription("小浣熊干脆面真好吃");
            elasticsearchOperations.save(product);
        }
    
        /**
         * 查询一条文档
         */
        @Test
        public void queryIndex(){
            Product product = elasticsearchOperations.get("1", Product.class);
            System.out.println(product);
        }
    
        /**
         * 查询所有
         */
        @Test
        public void queryAllIndex(){
            SearchHits<Product> search = elasticsearchOperations.search(Query.findAll(), Product.class);
            System.out.println("总分数: "+search.getMaxScore());
            System.out.println("符合条件的条数: "+search.getTotalHits());
            for (SearchHit<Product> searchHit : search) {
                System.out.println(searchHit.getContent());
            }
        }
    
        /**
         * 删除一条文档
         */
        @Test
        public void  testDelete(){
            //根据Id删除
            elasticsearchOperations.delete("1",Product.class);
            //删除所有
         elasticsearchOperations.delete(Query.findAll(),Product.class);
        }
    
    }
    
    
    • 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

    RestHighLevelClient

    索引操作

    创建索引及映射

    @Test
    public void  createIndex() throws IOException {
        //创建索引请求,指定索引名
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
        //设置索引映射,参数1:json格式的映射结构 参数2:指定格式的类型(json)
        createIndexRequest.mapping("{\n" +
                                   "    \"properties\": {\n" +
                                   "      \"title\":{\n" +
                                   "        \"type\": \"keyword\"\n" +
                                   "      },\n" +
                                   "      \"price\":{\n" +
                                   "        \"type\": \"double\"\n" +
                                   "      },\n" +
                                   "      \"create_at\":{\n" +
                                   "        \"type\": \"date\"\n" +
                                   "      },\n" +
                                   "      \"description\":{\n" +
                                   "        \"type\": \"text\"\n" +
                                   "      }\n" +
                                   "    }\n" +
                                   "  }", XContentType.JSON);
    
        //参数1:创建索引请求  ,参数2:索引请求的配置对象,一般直接用默认的
        //返回对象包含的索引的创建状态
        CreateIndexResponse response = elasticsearchClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        //Acknowledged属性表示了索引是否创建成功
        System.out.println(response.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

    删除索引

    /**
         * 删除索引
         */
        @Test
        public void testDeleteIndex() throws IOException {
            /*参数1:删除索引对象 参数2:请求配置对象*/
            //返回操作结果
            AcknowledgedResponse response = elasticsearchClient.indices().delete(new DeleteIndexRequest("product"), RequestOptions.DEFAULT);
            System.out.println("删除结果:"+response.isAcknowledged());
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    文档操作

    创建文档

     /**
          创建文档
         */
        @Test
        public void createDoc() throws IOException {
    
            //创建请求索引对象,需要传入索引的名称
            IndexRequest indexRequest = new IndexRequest("product");
            //可指定id,不指定就UUID,一般传入 json格式的文档
            indexRequest.id("1").source("{\n" +
                    "  \"title\":\"红烧牛肉面\",\n" +
                    "  \"price\":\"5.5\",\n" +
                    "  \"create_at\":\"2022-04-13\",\n" +
                    "  \"description\":\"红烧牛肉面真难吃\"\n" +
                    "}", XContentType.JSON);
    
            //参数1: 索引的请求对象 ,参数2:请求配置对象
            IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
            System.out.println(response.status());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    更新文档

      /**
         * 更新文档
         */
        @Test
        public void updateDoc() throws IOException {
            //参数1:索引名,参数2:文档id
            UpdateRequest updateRequest = new UpdateRequest("product","1");
            updateRequest.doc("{\n" +
                    "    \"description\":\"新:好饿想吃\"\n" +
                    "  }",XContentType.JSON);
            UpdateResponse response = elasticsearchClient.update(updateRequest, RequestOptions.DEFAULT);
            System.out.println(response.status());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    删除文档

     /**
         * 删除文档
         */
        @Test
        public void deleteDoc() throws  IOException{
            //参数1:索引名,参数2:id值
            DeleteRequest deleteRequest = new DeleteRequest("product","1");
            DeleteResponse response = elasticsearchClient.delete(deleteRequest, RequestOptions.DEFAULT);
            System.out.println(response.status());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查询文档

    /**
         * 根据ID查询文档
         */
        @Test
        public void queryDoc() throws IOException {
    
            GetRequest getRequest = new GetRequest("product","1");
            GetResponse response = elasticsearchClient.get(getRequest, RequestOptions.DEFAULT);
            System.out.println("ID:"+response.getId());
            System.out.println("数据:"+response.getSourceAsString());
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    高级查询

    查询所有

    /**
         * 查询所有
         */
        @Test
        public void queryAll() throws IOException {
    
            //指定搜索的索引
            SearchRequest searchRequest = new SearchRequest("product");
            //指定查询条件
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //查询所有
            sourceBuilder.query(QueryBuilders.matchAllQuery());
    
            searchRequest.source(sourceBuilder);
    
            //参数1 :搜索的请求对象 参数2:请求配置对象
            SearchResponse response = elasticsearchClient.search(searchRequest,RequestOptions.DEFAULT);
            System.out.println("总记录数:"+response.getHits().getTotalHits().value);
            System.out.println("最大得分:"+response.getHits().getMaxScore());
    
            //获取结果
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("Id:"+hit.getId());
                System.out.println("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

    关键词查询

    /**
         * 不同条件查询 term(关键词查询)
         */
        @Test
        public void termQuery() throws IOException {
    
            //指定搜索的索引
            SearchRequest searchRequest = new SearchRequest("product");
            //指定查询条件
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(QueryBuilders.termQuery("description","吃"));
            searchRequest.source(sourceBuilder);
            SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
            System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;
    
            SearchHit[] hits = response.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

    封装高级查询

    public void queryBasic(QueryBuilder queryBuilder) throws IOException {
            //指定搜索的索引
            SearchRequest searchRequest = new SearchRequest("product");
            //指定查询条件
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(queryBuilder);
            searchRequest.source(sourceBuilder);
            SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
            System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;
    
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());;
    
            }
        }
    
        /**
         * 封装查询
         * @throws IOException
         */
        @Test
        public void queryTest() throws IOException {
            //1.term 关键词查询
            queryBasic(QueryBuilders.termQuery("description","吃"));
            //2.range  范围查询
            queryBasic(QueryBuilders.rangeQuery("price").gt(0).lte(10));
            //3.prefix 前缀查询
            queryBasic(QueryBuilders.prefixQuery("description","红烧牛肉面"));
            //4.wildcard 通配符查询  ?表示一个字符  *表示任意个字符
            queryBasic(QueryBuilders.wildcardQuery("title","红烧*"));
            //5.ids 多个指定id查询
            queryBasic(QueryBuilders.idsQuery().addIds("1").addIds("2"));
            //6.multi_math 多字段查询
            queryBasic(QueryBuilders.multiMatchQuery("红烧","title","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

    综合查询

    /*
            1.关键字查询 term
            2.分页查询 from size
            3.排序  sort
            4.返回指定的字段 fetchSource 用来指定查询返回的字段
         */
        @SneakyThrows
        @Test
        public void queryLimit() throws IOException {
            SearchRequest searchRequest = new SearchRequest("product");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
            //创建高亮器
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");
    
    
            searchSourceBuilder.query(QueryBuilders.termQuery("description","面"))
                    .from(0) //起始位置   (page-1)*size
                    .size(1) //每页的数量
    
                    .sort("price", SortOrder.DESC) // 1.排序的字段 2.排序的方式
                    .fetchSource(new String[]{}, new String[]{"create_at"}) // 1.包含的字段  2.想要排除的字段
                        .highlighter(highlightBuilder); //高亮查询
    
            searchRequest.source(searchSourceBuilder);
            SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
    
            System.out.println("符合条件的数量:" + response.getHits().getTotalHits().value);
    
            System.out.println("获得文档最大分数:" + response.getHits().getMaxScore());
    
    
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println("id:" + hit.getId() + " source:" + hit.getSourceAsString());
    
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields.containsKey("description")) {
                    System.out.println("description高亮结果:" + highlightFields.get("description").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

    基于对象操作

    Java类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Snacks {
    
        private Integer id;
    
        private String title;
    
        private Double price;
    
        private String description;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试

    /*
          将对象放入 ES中
         */
        @Test
        public  void createIndex() throws IOException {
            Snacks snacks = new Snacks();
            snacks.setId(1);
            snacks.setTitle("卫龙辣条");
            snacks.setPrice(0.5);
            snacks.setDescription("辣条真好吃");
    
            IndexRequest indexRequest = new IndexRequest("snacks");
            indexRequest.id(snacks.getId().toString())
                		//将对象转化为Json
                        .source(new ObjectMapper().writeValueAsString(snacks), XContentType.JSON);
    
    
            IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
            System.out.println("创建结果:"+response.status());
        }
    
        @Test
        public void queryTest() throws IOException {
    
            SearchRequest searchRequest = new SearchRequest("snacks");
    
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");
            sourceBuilder.query(QueryBuilders.termQuery("description","好吃"))
                         .highlighter(highlightBuilder);
    
    
            searchRequest.source(sourceBuilder);
    
            SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
    
            SearchHit[] hits = response.getHits().getHits();
            List<Snacks> list=new ArrayList<>();
            for (SearchHit hit : hits) {
                System.out.println(hit.getSourceAsString());
                //将json转换为对象
                Snacks snacks = new ObjectMapper().readValue(hit.getSourceAsString(), Snacks.class);
    
                //处理高亮
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields.containsKey("description")){
                    snacks.setDescription(highlightFields.get("description").fragments()[0].toString());
                }
                list.add(snacks);
            }
    
            for (Snacks snacks : list) {
                System.out.println(snacks);
            }
        }
    
    • 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

  • 相关阅读:
    sql注入之高权限注入和文件读写
    NOKOV动作捕捉系统使多场协同无人机自主建造成为可能
    【Spring容器的启动过程】
    视频监控平台功能:国外的硬盘录像机NVR通过ISUP协议(原ehome协议)接入AS-V1000视频平台
    SpringBoot 玩一玩代码混淆,防止反编译代码泄露!
    package-lock.json 有什么作用,如果项目中没有它会怎么样,举例说明
    人工智能与机器学习
    多线程理论基础
    数据结构——3道栈和队列OJ题
    Linux下查看pytorch运行时真正调用的cuda版本
  • 原文地址:https://blog.csdn.net/qq_50596778/article/details/125429384