SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)

SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)


文章目录

  • SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)
    • @[TOC]
  • 前言
  • 一、ElasticSearch是什么?
    • 1.基本概念
  • 二、集成步骤
    • 1.依赖引入
    • 2.文件配置
    • 3.RestHighLevelClient配置
    • 4.定义数据类型
    • 4.增删改查代码
    • 5.高级查询代码
  • 总结

章节
第一章链接: SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)
第二章链接: SpringBoot集成Elasticsearch7.x(2)|(复杂查询)
第三章链接: SpringBoot集成Elasticsearch7.x(3)|(aggregations之指标聚合查询)
第四章链接: SpringBoot集成Elasticsearch7.x(4)|(aggregations之分桶聚合查询)
第五章链接: SpringBoot集成Elasticsearch7.x(5)|(term、match、match_phrase区别)
第六章链接: SpringBoot集成Elasticsearch8.x(6)|(新版本Java API Client使用)
第七章链接: SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)

前言

本章节主要介绍SpringBoot项目集成ElasticSearch的一些相关知识,包括集成版本、依赖、集成方式、以及增删改查的使用。查看需要对Springboot项目有一定的了解。本文将采用官方推荐使用的Java High Level REST Client方式实现ElasticSearch操作。

一、ElasticSearch是什么?

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。

1.基本概念

Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。我们将 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比如下图

SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)_第1张图片

二、集成步骤

1.依赖引入

pom依赖如下,主要列出SpringBoot依赖版本以及ElasticSearch版本,其他需要依赖自行添加(本文使用的具体版本为elasticsearch-rest-high-level-client-7.12.1.jar)

    <!-- Springboot 版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.7</version>
        <relativePath/>
    </parent>
    
     <!-- ElasticSearch依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        

2.文件配置

yml配置ES对应参数

es:
  port: 9200
  servers: localhost

3.RestHighLevelClient配置

config配置,此处为单机配置,集群模式再次基础上修改也行

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
    @Value("${es.clusterName}")
    private String clusterName;
    @Value("${es.servers}")
    private String servers;
    @Value("${es.port}")
    private int port;
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(servers + ":" + port)
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

4.定义数据类型

定义数据类型,类似于mysql的表,定义好字段,该处用了lombok表达式,如不需要可自定义set、get方法取代 @Field()可以定义字段的类型以及分词等。

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
//@Document(indexName = "es_architecture")
public class ArchitectureDto {
    @ApiModelProperty(value = "id", required = true)
    @Id
    private String id;

    @ApiModelProperty(value = "建筑名称", required = true)
    @Field(type = FieldType.Text,analyzer = "ik-max-word")
    private String name;

    @ApiModelProperty(value = "所在省份", required = true)
    @Field(type = FieldType.Text)
    private String province;

    @ApiModelProperty(value = "所在城市", required = true)
    @Field(type = FieldType.Text)
    private String city;

    @ApiModelProperty(value = "所在区", required = true)
    @Field(type = FieldType.Text)
    private String area;

    @ApiModelProperty(value = "详细街道地址", required = true)
    @Field(type = FieldType.Text)
    private String address;

    @ApiModelProperty(value = "经纬度", required = true)
    private LocationPo location;

    @ApiModelProperty(value = "描述", required = true)
    @Field(type = FieldType.Text)
    private String description;

    @ApiModelProperty(value = "评分", required = true)
    @Field(type = FieldType.Double)
    private double score;

    @ApiModelProperty(value = "门票价格", required = true)
    @Field(type = FieldType.Double)
    private double price;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class LocationPo {

    @ApiModelProperty(value = "经度", required = true)
    private double lon;

    @ApiModelProperty(value = "纬度", required = true)
    private double lat;
}


4.增删改查代码

通过restHighLevelClient对象对ElasticSearch数据库进行操作,restHighLevelClient由springboot容器创建管理,用户不需要进行配置,使用的时候注入即可,本次使用的是测试类代码编写方式。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class EsHandTest {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 测试文档的添加
    @Test
    public void testCreateDoc() throws IOException {
    	//CreateDoc5()创建实体方法,可自己实现
        ArchitectureDto architectureDto = DocDemo.CreateDoc5();
        // 创建好index请求
        IndexRequest indexRequest = new IndexRequest("architecture_index");
        // 设置索引
        indexRequest.id("5");
        // 设置超时时间(默认)
        indexRequest.timeout(TimeValue.timeValueSeconds(5));
        // 往请求中添加数据
        indexRequest.source(JSON.toJSONString(architectureDto), XContentType.JSON);
        //执行添加请求
        IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(indexResponse);
    }

    @Test
    public void getDoc() throws IOException {
        //获得查询索引的请求对象
        GetRequest gerRequest = new GetRequest("architecture_index").id("2");
        //获得文档对象
        GetResponse doc = restHighLevelClient.get(gerRequest, RequestOptions.DEFAULT);
        //获得文档数据
        System.out.println(doc.getSourceAsString());
    }

    @Test
    public void delDoc() throws IOException {
        //获得删除的索引请求对象
        DeleteRequest delRequest = new DeleteRequest("architecture_index").id("1");
        //删除文档
        DeleteResponse delete = restHighLevelClient.delete(delRequest, RequestOptions.DEFAULT);
        System.out.println(delete.getIndex());
    }

    @Test
    public void delIndex() throws IOException {
        IndicesClient indices = restHighLevelClient.indices();
        DeleteIndexRequest delReq = new DeleteIndexRequest("architecture_index");
        AcknowledgedResponse delete = indices.delete(delReq, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }

    @Test
    public void contextLoads() throws IOException {
        //查询mysql中所有数据
        List<ArchitectureDto> architectures = new ArrayList<>();

        //创建批量处理对象
        BulkRequest bulkRequest = new BulkRequest();

        //循环添加新增处理请求
        for (ArchitectureDto architecture : architectures) {
            String architecturJson = JSON.toJSONString(architecture);
            IndexRequest indexRequest = new IndexRequest("architecture_index").id(architecture.getId() + "").source(architecturJson, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }

        //提交批量处理对象
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

        //查看添加状态
        System.out.println(bulk.status());

    }

5.高级查询代码

通过restHighLevelClient对象对ElasticSearch数据库进行高级查询操作

@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class EsSearchTest {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    /**
     * 查询条件数据    匹配查询不到将字段类似设置为.keyword
     * @throws IOException
     */
    @Test
    public void searchAll() throws IOException {
        //定义请求对象
        SearchRequest request = new SearchRequest("architecture_index");
        //制定检索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());   //查询所有
//        builder.query(QueryBuilders.termQuery("address","huahexi777"));    //非String 类型查询
//        builder.query(QueryBuilders.termQuery("location.lat",33.2));    //非String 类型查询
//        builder.query(QueryBuilders.matchPhraseQuery("area","高新区"));   //精准查询String
//        builder.query(QueryBuilders.matchQuery("area.keyword","高新区"));   // 不能匹配到
//        builder.query(QueryBuilders.termQuery("area.keyword","高新区"));
//        builder.sort("price", SortOrder.DESC);
        request.source(builder);
        //获得文档对象
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //获得文档数据
        for (SearchHit hit : search.getHits().getHits()) {
            ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
            System.out.println(JSON.toJSONString(art));
        }
    }

    /**
     * 类似于数据库的 or 查询
     * @throws IOException
     */
    @Test
    public void searchByBolt() throws IOException {
        //定义请求对象
        SearchRequest request = new SearchRequest("architecture_index");
        //制定检索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchQuery("price",10));
        boolQueryBuilder.should(QueryBuilders.matchQuery("score",4.6).boost(10));
        builder.query(boolQueryBuilder);    //非String 类型查询
        request.source(builder);
        //获得文档对象
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //获得文档数据
        for (SearchHit hit : search.getHits().getHits()) {
            ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
            System.out.println(JSON.toJSONString(art));
        }
    }

    /**
     * 查询部分字段
     * @throws IOException
     */
    @Test
    public void searchByParam() throws IOException {
        //定义请求对象
        SearchRequest request = new SearchRequest("architecture_index");
        //制定检索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());   //查询所有
        String[]  includes = {"name","address","price"};
        String[] excludes = {};
        /** 会多出一个score字段 默认值都为0 具体原因不详  */
        builder.fetchSource(includes,excludes);
        request.source(builder);
        //获得文档对象
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //获得文档数据
        for (SearchHit hit : search.getHits().getHits()) {
            ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
            System.out.println(JSON.toJSONString(art));
        }
    }

    /**
     * 范围查询 大于小于
     * @throws IOException
     */
    @Test
    public void searchByFilter() throws IOException {
        //定义请求对象
        SearchRequest request = new SearchRequest("architecture_index");
        //制定检索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //定制查询条件
        boolQueryBuilder.filter (QueryBuilders.rangeQuery("price").gte(10).lte(30));
        builder.query(boolQueryBuilder);    //非String 类型查询
        request.source(builder);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
            System.out.println(JSON.toJSONString(art));
        }
    }

    /**
     * 迷糊查询
     * @throws IOException
     */
    @Test
    public void searchByLike() throws IOException {
        //定义请求对象
        SearchRequest request = new SearchRequest("architecture_index");
        //制定检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //定制查询条件
        TermQueryBuilder builder = QueryBuilders.termQuery("name.keyword","北京大").fuzziness(Fuzziness.ONE));
        searchSourceBuilder.query(builder);
        request.source(searchSourceBuilder);

        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
            System.out.println(JSON.toJSONString(art));
        }
    }

}

总结

以上就是SpringBoot集成Elasticsearch数据库内容,在验证过程中遇到很多问题,如果大家在使用过程中遇到问题欢迎留言。

你可能感兴趣的:(springboot集成,elasticsearch,spring,boot,elasticsearch,java)