美文网首页
Springboot2.x 两种方式操作增删改查Elastics

Springboot2.x 两种方式操作增删改查Elastics

作者: 蓝胖子CC7 | 来源:发表于2022-03-11 17:02 被阅读0次

1. 概述

Springboot2 对Elasticsearch进行增删改查有多种方式:
通过ES的9300端口使用TCP的方式操作,该种方式已经逐渐被官方废弃,我们不再进行研究
我们主要使用通过ES的9200端口使用HTTP的方式

  • JestClient:非官方,更新慢
  • RestTemplate:模拟发 HTTP 请求,ES 很多操作需要自己封装,麻烦
  • HttpClient:同上
  • Elasticsearch-Rest-Client:官方 RestClient,封装了 ES 操作,API 层次分明,上手简单

我们选择使用最佳的方式Elasticsearch-Rest-Client
有两种引入依赖的方式:

  1. 只引入Elasticsearch-Rest-Client需要的包
  2. 直接引入Spring-data-elasticsearch,此时自动引入了Elasticsearch-Rest-Client,但是需要注意一下版本对应问题
    区别:使用Spring-data-elasticsearch依赖,可采用ElasticsearchRepository方式操作Entity实体对象,如要操作未知固定列的数据,还需要Elasticsearch-Rest-Client操作数据

关于Elasticsearch版本的选择:




Elasticsearch不同版本对系统的支持

参考链接:https://www.elastic.co/cn/support/matrix

关于Elasticsearch与JVM版本的选择:




Elasticsearch不同版本对JVM的支持

参考链接:https://www.elastic.co/cn/support/matrix#matrix_jvm

关于Spring-data-elasticsearch版本的选择:


版本对照图

参考链接:
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements

2. 代码示例

2.1

我以Elasticsearch6.8.21为例:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.8/java-rest-high-supported-apis.html

注:使用什么版本的es服务端,就引入相同版本号的依赖文件
1. 引入依赖文件

<dependency>
     <groupId>org.elasticsearch</groupId>
     <artifactId>elasticsearch</artifactId>
     <version>6.8.21</version>
</dependency>
<dependency>
     <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
     <version>6.8.21</version>
</dependency>

2. 配置RestHighLevelClient

@Configuration
public class ElasticsearchRestClientConfig {
    public static final RequestOptions COMMON_OPTIONS;
    static {
       RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
       COMMON_OPTIONS = builder.build();
    }

    /**
     * 创建ES实例
     * @return
     */
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        HttpHost httpHost = new HttpHost(
                "127.0.0.1",9200,"http"
        );
        RestClientBuilder restClientBuilder = RestClient.builder(httpHost);
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);
        return restHighLevelClient;
    }
}

3. 使用RestHighLevelClient操作数据
针对需要存储查询动态属性字段的数据,可采用该种方式;此方式也不需要对Springboot版本进行调整,我使用了Springboot2.6.x版本,依然可行。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchHighLevelClientTest {
    @Resource
    private RestHighLevelClient client;
    
    /**
     * 判断索引是否存在
     */
    @Test
    public void testCheckIndex () {
        try {
            boolean exist = client.indices().exists(new GetIndexRequest("indexName"), RequestOptions.DEFAULT);
            System.out.println(exist);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

   /**
     * 创建索引
     */
    @Test
    public void testCreateIndex (){
        try {
            CreateIndexRequest request = new CreateIndexRequest("indexName");
            CreateIndexResponse createIndexResponse = this.client.indices().create(request, RequestOptions.DEFAULT);
            System.out.println(createIndexResponse.index());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 删除索引
     */
    @Test
    public void testDeleteIndex() {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest("indexName");
            AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入数据
     */
    @Test
    public void testInsertMapData (){
        try {
            // 方法1:
            Map<String,Object> dataMap = new HashMap<>();
            dataMap.put("test", "test1");
            IndexRequest indexRequest = new IndexRequest("xc_course","doc");
            indexRequest.source(dataMap);
            IndexResponse indexResponse = this.client.index(indexRequest, RequestOptions.DEFAULT);
            System.out.println(indexResponse.getResult());
            //方法2:该发法采用批量插入的方法
            Map<String,Object> dataMap2 = new HashMap<>();
            dataMap2.put("city", "北京");
            IndexRequest indexRequest2 = new IndexRequest("xc_course","doc");
            indexRequest2.source(dataMap2);
            BulkRequest request = new BulkRequest();
            request.add(indexRequest2);
            BulkResponse bulkResponse = this.client.bulk(request, RequestOptions.DEFAULT);
            System.out.println(JSONObject.toJSONString(bulkResponse));
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 批量写入数据
     */
    @Test
    public void batchInsertMapData (){
        try {
            List<Map<String,Object>> userIndexList = new ArrayList<>();
            Map<String,Object> map1 = new HashMap<>();
            map1.put("test", "test1");
            Map<String,Object> map2 = new HashMap<>();
            map2.put("test", "test2");
            userIndexList.add(map1);
            userIndexList.add(map2);
            BulkRequest request = new BulkRequest();
            for (Map<String,Object> dataMap:userIndexList){
                request.add(new IndexRequest("xc_course","doc").source(dataMap));
            }
            BulkResponse bulkResponse = this.client.bulk(request, RequestOptions.DEFAULT);
            System.out.println(JSONObject.toJSONString(bulkResponse));
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 更新数据,可以直接修改索引结构
     */
    @Test
    public void testUpdateMapData (){
        try {
            Map<String,Object> dataMap = new HashMap<>();
            dataMap.put("test", "test2");
            dataMap.put("test1", "test3");
            UpdateRequest updateRequest = new UpdateRequest("xc_course","doc", "51zYd38BFz6qlQzXYT56");
            updateRequest.doc(dataMap);
            UpdateResponse updateResponse = this.client.update(updateRequest, RequestOptions.DEFAULT);
            System.out.println(updateResponse.getResult());
        } catch (Exception e){
            e.printStackTrace();
        }
    }
   /**
     * 删除数据
     */
    @Test
    public void testDeleteMapData (){
        try {
            //方法1:
            DeleteRequest deleteRequest1 = new DeleteRequest("xc_course","doc", "4VwadH8BFz6qlQzXVD5c");
            DeleteResponse deleteResponse1 = this.client.delete(deleteRequest1, RequestOptions.DEFAULT);
            System.out.println(deleteResponse1.getResult());
            //方法2:
            DeleteRequest deleteRequest2 = new DeleteRequest();
            deleteRequest2.index("xc_course");
            deleteRequest2.type("doc");
            deleteRequest2.id("41zJd38BFz6qlQzXhj71");
            DeleteResponse deleteResponse2 = this.client.delete(deleteRequest2, RequestOptions.DEFAULT);
            System.out.println(deleteResponse2.getResult());
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * 查询总数
     */
    @Test
    public void testCount (){
        // 指定创建时间
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
//        queryBuilder.must(QueryBuilders.termQuery("test", "test1"));

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(queryBuilder);

        CountRequest countRequest = new CountRequest("xc_course");
        countRequest.source(sourceBuilder);
        try {
            CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
            long count = countResponse.getCount();
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   /**
     * 查询集合
     */
    @Test
    public void testList () {
        // 查询条件,指定时间并过滤指定字段值
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
//        queryBuilder.must(QueryBuilders.termQuery("test", "test1"));
//        queryBuilder.mustNot(QueryBuilders.termQuery("city","北京"));
        sourceBuilder.query(queryBuilder);
        SearchRequest searchRequest = new SearchRequest("xc_course");
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse searchResp = client.search(searchRequest, RequestOptions.DEFAULT);
            List<Map<String,Object>> data = new ArrayList<>() ;
            SearchHit[] searchHitArr = searchResp.getHits().getHits();
            for (SearchHit searchHit:searchHitArr){
                Map<String,Object> temp = searchHit.getSourceAsMap();
                temp.put("id",searchHit.getId()) ;
                data.add(temp);
            }
            System.out.println(JSONObject.toJSONString(data));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    /**
     * 分页查询
     */
    @Test
    public void testPage () {
        // 查询条件,指定时间并过滤指定字段值
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(1);
        sourceBuilder.size(20);
        //sourceBuilder.sort("createTime", SortOrder.DESC);
        SearchRequest searchRequest = new SearchRequest("xc_course");
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse searchResp = client.search(searchRequest, RequestOptions.DEFAULT);
            List<Map<String,Object>> data = new ArrayList<>() ;
            SearchHit[] searchHitArr = searchResp.getHits().getHits();
            for (SearchHit searchHit:searchHitArr){
                Map<String,Object> temp = searchHit.getSourceAsMap();
                temp.put("id",searchHit.getId()) ;
                data.add(temp);
            }
            System.out.println(JSONObject.toJSONString(data));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.2

1. 引入依赖文件
① Springboot2.6.x版本过高,与Elasticsearch6.8.x不一致,使用中代码会出错,需要对Springboot版本进行降级处理
如下图:

springboot2.6.x版本的spring-boot-starter-data-elasticsearch引用的是4.3.x版本的spring-data-elasticsearch
4.3.x版本的spring-data-elasticsearch引用的是7.15.2版本的elasticsearch客户端

② 将Springboot版本降级至2.2.x后
依赖选择 spring-boot-starter-data-elasticsearch

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>-->

或者 spring-data-elasticsearch 3.2.x版本

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-elasticsearch</artifactId>
   <version>3.2.13.RELEASE</version>
</dependency>

2. 配置application.yml文件

spring:
  elasticsearch:
     rest:
        connection-timeout: 30s
        read-timeout: 60s
        uris: 127.0.0.1:9200

3. 使用ElasticsearchRepository操作实体数据

可参考官方文档:
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.repositories

也可以与第一种方式结合使用
官方也给出了相关RestHighLevelClient配置示例


使用RestHighLevelClient

客户端配置: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.rest
可扩充配置项:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration

相关文章

  • Springboot2.x 两种方式操作增删改查Elastics

    1. 概述 Springboot2 对Elasticsearch进行增删改查有多种方式:通过ES的9300端口使用...

  • 增删改

    对于表中的操作,就是增删改查,查内容较多,这里先说增删改。 1.增(insert或者load) 即插入数据,多行插...

  • SQL查询结构总结

    SQL 增删改查 对数据库有修改的操作是:增删改 增 insert into 表名 values(); 删 del...

  • JS字符串操作之增删改查

    之前写过一篇文章叫JS数组操作之增删改查,今天我就用同样的方式简单介绍一下JS字符串操作中常用函数的用法。 一、增...

  • mysql的插入语句

    MySQL增删改查之增insert、replace

  • 浅谈Redis持久化

    大家都知道Redis增删改查的操作比MYSQL增删改查操作要快。原因是MYSQL的增删改操作是在硬盘上直接操作,而...

  • GET请求和POST请求

    在HTTP协议中, 不同的方法对资源有不同的操作方式. 最常用的是GET和POST, 这两种方法都能做到增删改查....

  • 2018-01-11 JDBC连接数据库代码

    1.JDBC操作mysql数据库-增删改查 2.JDBC操作Oracle数据库-增删改查

  • MYSQL数据库的增删改查

    MYSQL数据库的增删改查 一.对于库的增删改查 增create database 库名称;create data...

  • nodejs+mongodb

    nodejs操作 mongodb数据库增删改查 创建node增删改查执行文件

网友评论

      本文标题:Springboot2.x 两种方式操作增删改查Elastics

      本文链接:https://www.haomeiwen.com/subject/tgsurrtx.html