SpringBoot 使用JestClient操作Elasticsearch

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介:

1.Jest介绍

image

操作Elasticsearch的客户端有很多,SpringBoot也提供了方式去操作,这里介绍另外一种方式去使用Elasticsearch --- JestClient

JestClient是一款基于HTTP方式操作的Elasticsearch的客户端,支持同步和异步操作,同时也可以结合ElasticSearch的依赖进行操作Elasticsearch。

支持多个版本的Elasticsearch,如下:

= 6.0.0 | 6
= 5.0.0 | 5
= 2.0.0 | 2
0.1.0 - 1.0.0 | 1

<= 0.0.6 | < 1

更多信息可以查看github,地址是:https://github.com/searchbox-io/Jest

2.SpringBoot整合JestClient

接下来介绍如何在SpringBoot中使用JestClient操作Elasticsearch。

2.1 前置工作

首先启动Elasticsearch,我这里是在本地启动的Elasticsearch,版本是6.8.2,为了方便查看数据,这里使用Elasticsearch-Head插件,如下图所示。

image

2.2 添加Jest依赖

创建项目,在pom文件中加入Jest依赖(这里根据上面版本对应添加依赖),这里额外添加量了elasticsearch和lombok为了方便操作,如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dalaoyang</groupId>
    <artifactId>springboot_jestclient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_jestclient</name>
    <description>springboot_jestclient</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.2.6.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.searchbox</groupId>
            <artifactId>jest</artifactId>
            <version>6.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.8.2</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.6.RELEASE</version>
            </plugin>
        </plugins>
    </build>

</project>

2.3 配置文件

在配置文件中添加elasticsearch相关配置,其中uris配置Elasticsearch的HTTP端口,如本文添加的配置:

spring.application.name=springboot_jestclient
# 应用服务web访问端口
server.port=8888

spring.elasticsearch.rest.uris=http://localhost:9200
spring.elasticsearch.jest.username=elastic
spring.elasticsearch.jest.password=elastic

到这里其实已经整合完成了,是不是非常简单?

3.Elasticsearch基本操作

接下介绍如何操作Elasticsearch,这里分别介绍如下几部分内容:

  • 索引文档
  • 索引类操作
  • 文档类操作
  • 查询操作

3.1 文档实体

这里创建一个Book文档做为示例,其中@JestId为文档id,即Elasticsearch中的_id字段,本文BookDocument内容如下:

package com.dalaoyang.document;

import io.searchbox.annotations.JestId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BookDocument {

    @JestId
    private String id;
    private String bookName;
    private String bookAuthor;
    private Integer pages;
    private String desc;
}

为了方便操作,这里创建了一个request对象进行操作,如下:

package com.dalaoyang.model;

import com.dalaoyang.document.BookDocument;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BookRequest {

    //删除文档用
    private String id;
    //查询用
    private String keyword;
    private String indexName;
    private String typeName;
    //新增文档用
    private BookDocument body;
}

在使用相关操作时,其实都是通过io.searchbox.client.JestClient#execute来进行操作(需要注意,这里没有对JestClient进行配置,只是使用的默认的配置),将对应动作当做参数传入,接下来介绍几个常用的动作。

3.2 索引类操作

结合MySQL来看的话,索引可以理解为一个数据库,索引相关的操作可能不是很多,这里介绍相对比较常用的是创建索引和删除索引,如下:

3.2.1 创建索引

CreateIndex createIndex = new CreateIndex.Builder(indexName).build();

3.2.2 删除索引

DeleteIndex deleteIndex = new DeleteIndex.Builder(indexName).build();

通过上面两个操作可以看到,都是通过使用对应的Index实体来操作对应实体,当然还有一些不是很常用的,如果有需要可以查看相关文档进行使用,这里不一一介绍了,完整s示例内容如下:

package com.dalaoyang.web;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @Autowired
    private JestClient jestClient;

    @GetMapping("createIndex")
    public String createIndex(String indexName) throws Exception{
        CreateIndex createIndex = new CreateIndex.Builder(indexName).build();
        JestResult result = jestClient.execute(createIndex);
        return result.getJsonString();
    }

    @GetMapping("deleteIndex")
    public String deleteIndex(String indexName) throws Exception{
        DeleteIndex deleteIndex = new DeleteIndex.Builder(indexName).build();
        JestResult result = jestClient.execute(deleteIndex);
        return result.getJsonString();
    }
}

3.3 文档类操作

文档相当于MySQL中的行记录,也就是说一条数据,由于新增和修改在同一个方法内,所以这里也是对新增(和修改)和删除方法进行介绍,如下:

3.3.1 新增或修改文档

首先会判断索引是否存在,不存在的话会根据索引文档进行创建索引,然后进行新增或修改操作,如果没有指定id的话(上文说的注解@JestId字段),会自动生成一个id。

Index.Builder builder = new Index.Builder(bookRequest.getBody());
Index index = builder.index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build();

这里使用新增文档创建三条数据方便后面查询,如下:

{
    "indexName": "book",
    "typeName": "book",
    "body": {"id":"test0001","bookName":"数学书","bookAuthor":"复旦大学","pages":100,"desc":"复旦大学的数学书"}
}
{
    "indexName": "book",
    "typeName": "book",
    "body": {"id":"test0003","bookName":"语文书","bookAuthor":"北京大学","pages":100,"desc":"北京大学的语文书"}
}
{
    "indexName": "book",
    "typeName": "book",
    "body": {"id":"test0003","bookName":"英文书","bookAuthor":"清华大学","pages":200,"desc":"清华大学的英文书"}
}

3.3.2 删除文档(根据id)

Delete index = new Delete.Builder(bookRequest.getId()).index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build();

完整示例内容如下:

package com.dalaoyang.web;

import com.dalaoyang.model.BookRequest;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Delete;
import io.searchbox.core.Index;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class DocumentController {

    @Autowired
    private JestClient jestClient;

    @PostMapping("saveOrUpdateDocument")
    public String saveOrUpdateDocument(@RequestBody BookRequest bookRequest) throws Exception{
        Index.Builder builder = new Index.Builder(bookRequest.getBody());
        Index index = builder.index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build();
        JestResult result = jestClient.execute(index);
        return result.getJsonString();
    }

    @PostMapping("deleteDocumentById")
    public String deleteDocumentById(@RequestBody BookRequest bookRequest) throws Exception{
        Delete index = new Delete.Builder(bookRequest.getId()).index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build();
        JestResult result = jestClient.execute(index);
        return result.getJsonString();
    }
}

3.4 查询操作

查询操作可能是对Elasticsearch最需要使用的场景,这里举一个简单的场景,输入关键字,查询对应book文档,关键字匹配(bookName,bookAuthor,desc)三个字段,这里结合Elasticsearch官方依赖进行操作,完整示例如下:


package com.dalaoyang.web;

import com.dalaoyang.model.BookRequest;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class QueryController {

    @Autowired
    private JestClient jestClient;

    @PostMapping("search")
    public String search(@RequestBody BookRequest bookRequest) throws Exception{
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(new MultiMatchQueryBuilder(bookRequest.getKeyword(), "bookName","bookAuthor","desc"));
        log.info(searchSourceBuilder.toString());
        SearchResult result = jestClient.execute(new Search.Builder(searchSourceBuilder.toString())
                .addIndex(bookRequest.getIndexName())
                .addType(bookRequest.getTypeName())
                .build());
        return result.getJsonString();
    }
}

比如这里搜索清华,这里我打印了一下查询语句,如下:

{
    "query":{
        "multi_match":{
            "query":"清华",
            "fields":[
                "bookAuthor^1.0",
                "bookName^1.0",
                "desc^1.0"
            ],
            "type":"best_fields",
            "operator":"OR",
            "slop":0,
            "prefix_length":0,
            "max_expansions":50,
            "zero_terms_query":"NONE",
            "auto_generate_synonyms_phrase_query":true,
            "fuzzy_transpositions":true,
            "boost":1
        }
    }
}

查询的结构只有一条,与在Elasticsearch-Head中查询一致,如图

image

4.一些建议

相关操作Elasticsearch的客户端有很多,这里就不做相关对比了,JestClient本人也在真实上线项目中使用过,这里只是在使用过几种的前提下做出几点建议:

  • Elastic官方已经开始建议使用HTTP方式去操作Elasticsearch了
  • 当初选择这种的原因是考虑到更好的去扩展版本,封装响应的操作类可以兼容更多的版本。
  • 在高版本的Elasticsearch中,有一些文档类型的内容被单独抽离出来了,比如父子文档。

5.源码

源码地址:https://gitee.com/dalaoyang/springboot_learn/tree/master/springboot_jestclient

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
2月前
|
JSON Java 网络架构
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
这篇文章介绍了如何使用Spring Boot整合REST方式来搭建和操作Elasticsearch服务。
134 4
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
|
1月前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
38 1
|
2月前
|
Web App开发 JavaScript Java
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
这篇文章是关于如何使用Spring Boot整合Elasticsearch,并通过REST客户端操作Elasticsearch,实现一个简单的搜索前后端,以及如何爬取京东数据到Elasticsearch的案例教程。
215 0
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
|
2月前
|
自然语言处理 Java Maven
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
这篇博客介绍了如何使用Spring Boot整合TransportClient搭建Elasticsearch服务,包括项目创建、Maven依赖、业务代码和测试示例。
112 0
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
|
2月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
55 0
|
2月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
37 0
|
4月前
|
网络协议 Java API
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
这篇文章介绍了如何在SpringBoot中整合Elasticsearch-Rest-Client,并提供了保存数据和进行复杂检索的测试示例。
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
|
27天前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
38 5
|
2月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
181 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
3月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo