网站黑链怎么做的中国网民博客 seo
说明:es操作索引库、文档,除了使用它们自带的命令外(参考:http://t.csdn.cn/4zpmi),在IDEA中可以添加相关的依赖,使用对应的API来操作。
准备工作
搭建一个SpringBoot项目,DAO使用的MyBatis-Plus,对数据库中的学生表进行操作。
pom.xml文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version><relativePath/></parent><groupId>org.hzy</groupId><artifactId>es_essay_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><elasticsearch.version>7.12.1</elasticsearch.version></properties><dependencies><!--spring web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!--数据库连接驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></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><!--FastJson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.71</version></dependency><!--commons依赖--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies>
</project>
在此之上,导入RestHighLevelClient依赖,并指定版本,不然会使用SpringBoot自带版本,依靠此依赖实现对ES的一系列操作。
<properties><elasticsearch.version>7.12.1</elasticsearch.version></properties><!--RestHighLevelClient依赖--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></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;/*** 初始化客户端*/@BeforeEachpublic void init(){client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.126.128:9200")));}/*** 关闭客户端* @throws IOException*/@AfterEachpublic void close() throws IOException {client.close();}
创建索引库
/*** 创建索引*/@Testpublic 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);}
执行成功
到ikbana上看下,索引库已经创建完成
获取索引库
/*** 获取索引库* @throws IOException*/@Testpublic 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类型,仅可知该索引库是否存在;
删除索引库
/*** 删除索引库* @throws IOException*/@Testpublic void deleteIndex() throws IOException {// 1. 创建请求DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("student");// 2. 发起请求client.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);}
删除索引库成功;
再次获取索引库,返回false;
小结
索引库没有修改操作
文档(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)*/@Testpublic 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平台,输入命令,可以查到对应的文档,说明新增文档成功;
查询文档
/*** 查询文档*/@Testpublic 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);}
查询完成;
删除文档
/*** 删除文档*/@Testpublic void delDoc() throws IOException {// 1.创建请求,删除ID为1的文档DeleteRequest request = new DeleteRequest("student").id("1");// 2.发起请求client.delete(request, RequestOptions.DEFAULT);}
执行完成;
再次查询,结果为null(注意,并不会报错);
更新文档
更新文档由两种方式,第一种是全局更新,其实也就是新增文档,代码是一样的,第二种是局部更新,代码如下:
/*** 更新文档(方式二:局部更新)*/@Testpublic 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);}
执行完成;
再次查找ID为1的文档,可以看到文档已更新;
批量导入文档
批量将数据库中的对象数据,导入到ES上;
/*** 批量导入文档(数据从数据库中查询获取)*/@Testpublic 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);}
执行完成,没有报错;
随便查找两条记录,可以看到都已经添加了进来;
总结
对于索引库的操作,请求是XxxIndexRequest(“索引库名”),创建是Create,删除是Delete,获取是Get(发起请求,方法名是exists);
对于文档的操作,请求是XxxRequest(“索引库名”,“ID”),新增是Index,删除是Delete,查询是Get,修改是Update,另外还有个批量的操作,是BulkRequest;