elasticsearch操作(API方式)

说明:es操作索引库、文档,除了使用它们自带的命令外(参考:http://t.csdn.cn/4zpmi),在IDEA中可以添加相关的依赖,使用对应的API来操作。

准备工作

搭建一个SpringBoot项目,DAO使用的MyBatis-Plus,对数据库中的学生表进行操作。

elasticsearch操作(API方式)_第1张图片

pom.xml文件


<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.10.RELEASEversion>
        <relativePath/>
    parent>

    <groupId>org.hzygroupId>
    <artifactId>es_essay_demoartifactId>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <maven.compiler.source>11maven.compiler.source>
        <maven.compiler.target>11maven.compiler.target>
        <elasticsearch.version>7.12.1elasticsearch.version>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.4.2version>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>1.2.71version>
        dependency>

        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
        dependency>
    dependencies>
project>

在此之上,导入RestHighLevelClient依赖,并指定版本,不然会使用SpringBoot自带版本,依靠此依赖实现对ES的一系列操作。

    <properties>
        <elasticsearch.version>7.12.1elasticsearch.version>
    properties>
    
	
	<dependency>
	    <groupId>org.elasticsearch.clientgroupId>
	    <artifactId>elasticsearch-rest-high-level-clientartifactId>
	dependency>

编写与学生类相关的索引库DSL语句,注意这里特意把学生类中的创建日期、入学日期合并成一个joinInfo字段,后面添加文档时需要考虑到这点;

PUT /student
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
        
      "username":{
        "type": "keyword",
        "copy_to": "all"
      },
        
      "password":{
        "type": "keyword",
        "index": false
      },
        
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },

      "gender":{
        "type": "keyword"
      },
        
      "image":{
        "type": "keyword"
      },
        
      "job":{
        "type": "integer"
      },
	  
	  "joinInfo":{
		"type": "keyword"
	  },
        
      "updateTime":{
        "type": "keyword"
      },
        
        
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

将上面索引库的DSL语句,在IDEA中用一个常量来存储,以便后面使用,注意前面“PUT /student”需要去掉,只需要最外层花括号内的信息即可;

public class Constants {

    public static final String CREATE_INDEX_STRING = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "        \n" +
            "      \"username\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "        \n" +
            "      \"password\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "        \n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "\n" +
            "      \"gender\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "        \n" +
            "      \"image\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "        \n" +
            "      \"job\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "\t  \n" +
            "\t  \"joinInfo\":{\n" +
            "\t\t\"type\": \"keyword\"\n" +
            "\t  },\n" +
            "        \n" +
            "      \"updateTime\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "        \n" +
            "        \n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";
}

索引库(index)操作

为了后面操作方便,把RestHighLevelClient的定义、创建、关闭放在方法外面,以下操作都是在测试类中实现;

    /**
     * 定义连接
     */
    private RestHighLevelClient client;

    /**
     * 初始化客户端
     */
    @BeforeEach
    public void init(){
        client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.126.128:9200")));
    }

    /**
     * 关闭客户端
     * @throws IOException
     */
    @AfterEach
    public void close() throws IOException {
        client.close();
    }

创建索引库

    /**
     *  创建索引
     */
    @Test
    public void addIndex() throws IOException {
        // 1.创建请求
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("student");

        // 2.编写DSL语句
        createIndexRequest.source(CREATE_INDEX_STRING, XContentType.JSON);

        // 3.发起请求
        client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
    }

执行成功

elasticsearch操作(API方式)_第2张图片

到ikbana上看下,索引库已经创建完成

elasticsearch操作(API方式)_第3张图片

获取索引库

    /**
     * 获取索引库
     * @throws IOException
     */
    @Test
    public void getIndex() throws IOException {
        // 1.创建请求
        GetIndexRequest getIndexRequest = new GetIndexRequest("student");

        // 2.发起请求
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);

        System.out.println("exists = " + exists);
    }

此方法返回结果为boolean类型,仅可知该索引库是否存在;

elasticsearch操作(API方式)_第4张图片

删除索引库

    /**
     * 删除索引库
     * @throws IOException
     */
    @Test
    public void deleteIndex() throws IOException {
        // 1. 创建请求
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("student");

        // 2. 发起请求
        client.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
    }

删除索引库成功;

elasticsearch操作(API方式)_第5张图片

再次获取索引库,返回false;

elasticsearch操作(API方式)_第6张图片

小结

索引库没有修改操作

文档(document)操作

再提一次,文档操作等同于数据库的数据操作,即类比数据的CRUD操作;

新增文档

注意,因为数据库中查询到的记录与ES的文档的字段并不是一一对应的,需要再创建一个对象来进行拼凑;

(Student类)

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

@Data
@TableName("tb_student")
public class Student implements Serializable {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer gender;
    private String image;
    private Integer job;
    private String entryDate;
    private String createTime;
    private String updateTime;
}

(StudentDoc类,与ES文档一一对应)

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
public class StudentDoc implements Serializable {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer gender;
    private String image;
    private Integer job;
    private String joinInfo;
    private String updateTime;

    public StudentDoc(Student student) {
        this.id = student.getId();
        this.username = student.getUsername();
        this.password = student.getPassword();
        this.name = student.getName();
        this.gender = student.getGender();
        this.image = student.getImage();
        this.job = student.getJob();
        this.joinInfo = "[创建日期:" + student.getCreateTime() + "], [加入日期:" + student.getEntryDate() +"]";
        this.updateTime = student.getUpdateTime();
    }
}
    /**
     * 新增文档(数据来自数据库,然后新增到ES)
     */
    @Test
    public void addDoc() throws IOException {
        // 1.查询数据(ID为1的记录)
        Student student = studentService.getById(1);
		
		// 1.1 拼凑文档
        StudentDoc studentDoc = new StudentDoc(student);

        // 2.创建请求
        IndexRequest request = new IndexRequest("student").id(student.getId().toString());

        // 3.编写DSL语句
        request.source(JSON.toJSONString(studentDoc),XContentType.JSON);

        // 4.发送请求
        client.index(request,RequestOptions.DEFAULT);
    }

执行完成;

在这里插入图片描述

查看kibana平台,输入命令,可以查到对应的文档,说明新增文档成功;

elasticsearch操作(API方式)_第7张图片

查询文档

    /**
     * 查询文档
     */
    @Test
    public void getDoc() throws IOException {
        // 1.创建请求,查询ID为1的文档
        GetRequest request = new GetRequest("student").id("1");

        // 2.发送请求
        GetResponse response = client.get(request, RequestOptions.DEFAULT);

        // 3.获取返回值
        String json = response.getSourceAsString();

        // 4.解析返回值为java对象
        StudentDoc studentDoc = JSON.parseObject(json, StudentDoc.class);

        System.out.println("studentDoc = " + studentDoc);
    }

查询完成;

在这里插入图片描述

删除文档

    /**
     * 删除文档
     */
    @Test
    public void delDoc() throws IOException {
        // 1.创建请求,删除ID为1的文档
        DeleteRequest request = new DeleteRequest("student").id("1");

        // 2.发起请求
        client.delete(request, RequestOptions.DEFAULT);
    }

执行完成;

elasticsearch操作(API方式)_第8张图片
再次查询,结果为null(注意,并不会报错);

elasticsearch操作(API方式)_第9张图片

更新文档

更新文档由两种方式,第一种是全局更新,其实也就是新增文档,代码是一样的,第二种是局部更新,代码如下:

    /**
     * 更新文档(方式二:局部更新)
     */
    @Test
    public void updateDoc() throws IOException {
        // 1.创建请求,修改ID为1的文档
        UpdateRequest request = new UpdateRequest("student","1");

        // 2.指定要修改的字段
        request.doc("name","徐志摩",
                "username","xuzhimo");

        // 3.发送请求
        client.update(request,RequestOptions.DEFAULT);
    }

执行完成;

elasticsearch操作(API方式)_第10张图片
再次查找ID为1的文档,可以看到文档已更新;

在这里插入图片描述

批量导入文档

批量将数据库中的对象数据,导入到ES上;

    /**
     * 批量导入文档(数据从数据库中查询获取)
     */
    @Test
    public void addDocs() throws IOException {
        // 1.获取所有学生的数据
        List<Student> students = studentService.list();

        // 2.创建Bulk请求
        BulkRequest bulkRequest = new BulkRequest();

        // 3.添加数据到Bulk中
        for (Student student : students) {
            // 3.1 创建Doc对象
            StudentDoc studentDoc = new StudentDoc(student);

            // 3.2 创建新增文档请求并将Doc对象放入
            bulkRequest.add(new IndexRequest("student").id(studentDoc.getId().toString())
                    .source(JSON.toJSONString(studentDoc),XContentType.JSON));
        }

        // 4.发送请求
        client.bulk(bulkRequest,RequestOptions.DEFAULT);
    }

执行完成,没有报错;

elasticsearch操作(API方式)_第11张图片

随便查找两条记录,可以看到都已经添加了进来;

在这里插入图片描述
在这里插入图片描述

总结

对于索引库的操作,请求是XxxIndexRequest(“索引库名”),创建是Create,删除是Delete,获取是Get(发起请求,方法名是exists);

对于文档的操作,请求是XxxRequest(“索引库名”,“ID”),新增是Index,删除是Delete,查询是Get,修改是Update,另外还有个批量的操作,是BulkRequest;

你可能感兴趣的:(elasticsearch,搜索引擎,IDEA)