SpringBoot集成ElasticSearch之文档的CRUD操作详解

目录

1、SpringBoot集成ElasticSearch

2、ElasticSearch之文档的基本操作(增删改查)

3、通过RestHighClient操作ES索引

(1)配置RestHighClient对象

(2)通过注解的方式获取对象

(3)操作文档的API


1、SpringBoot集成ElasticSearch

在创建项目时,选择elasticsearch选项

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

注意:版本兼容的问题,不同版本的SpringBoot有对应的ElasticSearch版本

如SpringBoot2.5版本对应ES-7.11.X

2、ElasticSearch之文档的基本操作(增删改查)

ES提供了基于HTTP协议的RESTful API用于操作文档,使用Kibana中的开发工具,可以方便的执行以下操作(不仅限下述方法):

索引中文档的基本操作方法
方法功能
PUT创建索引数据
GET查询文档
POST修改文档
DELETE删除文档
HEAD检查某文档是否存在

      ES是面向文档的,文档是es中可搜索的最小单位ES的文档由一个或多个字段组成,类似于关系型数据库中的一行记录,但ES的文档是以JSON进行序列化并保存的,每个JSON对象由一个或多个字段组成,字段类型可以是布尔,数值,字符串、二进制、日期等数据类型。

3、通过RestHighClient操作ES索引

(1)配置RestHighClient对象

/**
 * Spring的两步骤:
 * 1、找对象
 * 2、放入Spring容器中待用
 *
 */
@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                new HttpHost("127.0.0.1",9200,"http")
        ));
        return client;
    }
}

(2)通过注解的方式获取对象

    @Autowired
    @Qualifier("restHighLevelClient")//通过指定的方法,获取对象
    private RestHighLevelClient client;

(3)操作文档的API

    对于文档的CRUD操作存在同步和异步两种操作,当执行同步操作时,客户端需要等待xxxResponse('xxx'表示文档的一种操作方法)返回后才能继续执行其他操作,而执行异步操作(xxxAsync)则不需要等待客户端的响应。

1)创建索引

PUT /<target>/_doc/<_id>

IndexRequest中提供了以下重载的方法,根据指定的数据源创建索引

根据源码中的提示可知,推荐使用上述两种方式指定索引的数据源

    /**
     * Sets the document source to index.
     *
     * Note, its preferable to either set it using {@link #source(org.elasticsearch.common.xcontent.XContentBuilder)}
     * or using the {@link #source(byte[], XContentType)}.
     */
    public IndexRequest source(String source, XContentType xContentType) {
        return source(new BytesArray(source), xContentType);
    }
    @Test
    void indexDocumentTest() throws IOException {

        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.field("user", "kimchy");
            builder.timeField("postDate", new Date());
            builder.field("message", "trying out Elasticsearch");
        }
        builder.endObject();
        IndexRequest indexRequest = new IndexRequest("posts")
                .id("3").source(builder);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(indexResponse);
    }

2)查询文档

GET /index/_doc/id

    /**
     * 获取文档信息
     * @throws IOException
     */
    @Test
    void getDocTest() throws IOException {
        GetRequest getRequest = new GetRequest("posts", "1");

        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);

        Map<String, Object> source = response.getSourceAsMap();
        for (Map.Entry<String, Object> entry : source.entrySet()) {
            System.out.println(entry.getKey() + " , " + entry.getValue());
        }
    }

 

 /**
     * GetSourceRequest 专门用于获取文档的_source资源
     *
     * @throws IOException
     */
    @Test
    void getSourceTest() throws IOException {
        //专用于获取某一个文档的_source资源信息
        GetSourceRequest getSourceRequest = new GetSourceRequest("posts", "1");
        GetSourceResponse sourceResponse = client.getSource(getSourceRequest, RequestOptions.DEFAULT);
        sourceResponse.getSource().forEach((key, value) -> System.out.println(key + " , " + value));
    }

 

3)删除文档

DELETE /<index>/_doc/<_id>

    @Test
    void deleteDocTest() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("posts", "2");
        deleteRequest.timeout("1s");
        deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
        
        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(deleteResponse.status());
        System.out.println(deleteResponse.toString());
    }

4) 更新文档

POST /<index>/_update/<_id>

UPDATE API操作可以通过使用一个脚本或者传入部分文档信息,从而更新文档内容;

文档是不可变的,其不能被修改,只能被替换。

/**
     * 更新文档信息
     * @throws IOException
     */
    @Test
    void updateDocTest() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("posts", "2");
        updateRequest.timeout(TimeValue.timeValueMillis(10000));

        //使用脚本来更新文档信息(有错误,待解决)
        // Caused by: ElasticsearchException[Elasticsearch exception [type=null_pointer_exception, reason=null]] 

        //报错原因是参数异常,在当前索引下/posts/_doc/2 对应的_source中没有field字段,所以脚本执行报错 
        Map<String, Object> parameters = Collections.singletonMap("count", 4);

        //该脚本可以作为内联脚本提供,或者存储脚本ScriptType.STORED
        Script inline = new Script(ScriptType.INLINE, "painless",
                "ctx._source.field += params.count", parameters);
        updateRequest.script(inline);

//        updateRequest.upsert() 更新的文档可能不存在,则将更新内容新建为一个文档索引
        UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);

        System.out.println(response.toString());

        //根据数据的映射,更新对应的值
       /* HashMap<String, Object> update = new HashMap<>();
        update.put("name","Lilard2");
        update.put("birth","1996-11-03");
        updateRequest.doc(update);*/

    }

通过kibana的开发工具,演示更新文档的操作效果:

创建一个新的文档:

PUT /test/_doc/1?pretty
{
  "counter" : 1,
  "tags" : ["red"]
}

通过脚本传递参数,将counter值执行加5的操作:

POST /test/_update/1?pretty
{
  "script" : {
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params" : {
      "count" : 8
    }
  }
}

查询更新后的文档内容,_source中counter对应的结果为9:

{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "_seq_no" : 9,
  "_primary_term" : 6,
  "found" : true,
  "_source" : {
    "counter" : 9,
    "tags" : [
      "red"
    ]
  }
}

同样的,可以使用更新操作,为标签列表添加或者删除一个标签:

POST /test/_update/1?pretty
{
  "script": {
    "source": "ctx._source.tags.add(params.tag)",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

结果为:
{
  "_index" : "test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "_seq_no" : 10,
  "_primary_term" : 6,
  "found" : true,
  "_source" : {
    "counter" : 9,
    "tags" : [
      "red",
      "blue"
    ]
  }
}

 

参考链接:

        https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html

        https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.11/java-rest-high-document-update.html

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值