1.直击ES作用
遇到了什么问题? 随着互联网时代的蓬勃发展,网络上的数据量越来越丰富.用户的需求越来越特殊. 传统数据库(将数据存放在硬盘上的数据-mysql),不足以支撑复杂的搜索问题.技术的更新势在必行. 哪个技术可以解决这个问题? ElasticSearch/solr: 非关系型数据库的一种 都是基于Lucene封装的. Lucene是使用java语言编写的搜索引擎API 这个技术的使用方式? 安装: 创建索引库(表): mapping映射(字段名,字段类型,字段约束,是否参与搜索..) ...
2.ES原理
正向索引
select * from 表名 where age = 18; 执行过程: 从数据库表中从上到下一条一条的取出数据,如果满足条件则留下此数据,如果不满足条件则忽略数据
倒排索引
倒排索引: 将被搜索的字段逐行遍历,并进行分词,建立词条与文档ID的对应关系
3.ES名词解释
词条(term): 一个中文词语就是一个词条(你好 数据库 我爱你) 文档(Document): 一条数据就是一个文档 索引(Index): 相同类型文档的集合 映射(Mapping): 索引中字段的约束信息 type: 字段类型 字符串类型: text: 参与分词 keyword: 不参与分词 index: 字段是否参与搜索 默认值为true analyzer: 是否分词 自带: standard IK: ik_smart ik_max_word properties: 是否有子字段
4.ES使用
操作索引库和文档数据-DSL
# ES启动后就是一个web项目,直接向这个web项目发送RESTFul风格的请求即可操作es. # RESTFul风格的请求: # GET: 查询 # POST: 添加 # PUT: 修改 # DELETE: 删除 DSL POST /_analyze { "text": "学习java太棒了" } PUT /house GET /house DELETE /house # ES中自带的分词器叫standard(标准分词器),对中文不友好 POST /_analyze { "text": "中华人民共和国万岁", "analyzer": "standard" } # 给ES安装ik分词器插件 # ik_smart: 聪明的 # ik_max_word: 最大词汇量分词 POST /_analyze { "text": "中华人民共和国万岁", "analyzer": "ik_smart" } POST /_analyze { "text": "中华人民共和国万岁", "analyzer": "ik_max_word" } POST /_analyze { "text": "哎哟呵奥利给风起来了", "analyzer": "ik_max_word" } # 扩展词 # 停用词 #=====================索引库操作================== # 创建索引库 # 创建空索引库 PUT /test # 创建带有映射关系的索引 PUT /test { "mappings": { "properties": { "name":{ "type": "text", "index": true, "analyzer": "ik_smart" }, "age":{ "type": "integer", "index": true }, "email":{ "type": "keyword", "index": false } } } } # 查看索引库 GET /test # 查看索引库的映射信息 GET /test/_mapping # 删除索引库 DELETE /test # 修改索引库(通过修改索引库,添加新字段) PUT /test/_mapping { "properties":{ "gender":{ "type":"keyword" } } } #===========================文档操作=================== # 添加文档数据 POST /test/_doc/1 { "name":"大幂幂", "age":18, "gender":"女", "email":"damimi@qq.com" } POST /test/_doc/1 { "name":"大幂幂", "age":18, "gender":"女", "email":"damimi@qq.com" } POST /test/_doc { "name":"大幂幂2", "age":19, "gender":"女", "email":"damimi2@qq.com" } # 根据ID查询文档信息 // 6jP2yIoBwd3FfZ8R0WH0 GET /test/_doc/1 GET /test/_doc/XwYKH4kBS7Wd-2ayukAE # 根据ID删除文档数据 DELETE /test/_doc/XwYKH4kBS7Wd-2ayukAE # 修改-全量修改(覆盖) PUT /test/_doc/1 { "name":"大幂幂", "age":18, "gender":"女", "email":"damimi@qq.com" } # 修改-增量修改(修改指定字段) POST /test/_update/1 { "doc":{ "name":"柳岩" } }
通过java代码操作ES
官网:Elasticsearch Platform — Find real-time answers at scale | Elastic
项目中导入ES依赖
Maven Repository | Java REST Client [7.12] | Elastic
高版本
<?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> <groupId>org.example</groupId> <artifactId>WindTest</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>es</module> </modules> <!-- springboot父工程 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.5</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.12.1</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
低版本
<?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> <groupId>com.bw.es</groupId> <artifactId>day0704-01-es</artifactId> <version>1.0-SNAPSHOT</version> <!-- springboot父工程 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> </parent> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <!-- 指定导入的es版本 --> <elasticsearch.version>7.12.1</elasticsearch.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.12.1</version> </dependency> </dependencies> </project>
创建ES核心对象
并将对象存放到ioc容器中
Initialization | Java REST Client [7.12] | Elastic
package com.wind; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; public class Main { public static void main(String[] args) { System.out.println("Hello world!"); } @Bean public RestHighLevelClient createRestHighLevelClient(){ RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); return client; } }
操作索引库
package com.wind.es; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.client.indices.GetIndexResponse; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import java.io.IOException; import java.util.Map; @SpringBootTest public class test { @Resource private RestHighLevelClient esClient; /* //1.创建请求语义对象(本次访问es要做什么操作) // 设置请求携带的参数 //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 3.处理结果信息 todo: java代码操作es的索引库 创建索引库 查看索引库 删除索引库 修改索引库 */ @Test //创建 public void addIndex() throws IOException { //1.创建请求语义对象(本次访问es要做什么事情) // CreateIndexRequest: 本次请求为的是创建索引 CreateIndexRequest request = new CreateIndexRequest("test2"); // 设置请求携带的参数 request.mapping("_doc", "{\n" + " \"properties\": {\n" + " \"name\":{\n" + " \"type\": \"text\",\n" + " \"index\": true,\n" + " \"analyzer\": \"ik_smart\"\n" + " },\n" + " \"age\":{\n" + " \"type\": \"integer\",\n" + " \"index\": true\n" + " },\n" + " \"email\":{\n" + " \"type\": \"keyword\",\n" + " \"index\": false\n" + " }\n" + " }\n" + " }", XContentType.JSON); //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT); //3.处理结果信息 boolean flag = response.isAcknowledged(); System.out.println(flag); } @Test //查看 public void getIndex() throws IOException { //1.创建请求语义对象(本次访问es要做什么操作) GetIndexRequest request = new GetIndexRequest("test2"); //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT); //3.处理结果信息 Map<String, Object> map = response.getMappings().get("test2").getSourceAsMap(); System.out.println(map); System.out.println(response); } @Test //修改 public void updateIndex() throws IOException { //1.创建请求语义对象(本次访问es要做什么操作) PutMappingRequest request = new PutMappingRequest("test2"); //构建参数 request.source( "{\n" + " \"properties\": {\n" + " \"message\": {\n" + " \"type\": \"text\"\n" + " }\n" + " }\n" + "}", XContentType.JSON); //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 AcknowledgedResponse putMappingResponse = esClient.indices().putMapping(request, RequestOptions.DEFAULT); //3.处理结果信息 boolean acknowledged = putMappingResponse.isAcknowledged(); System.out.println(acknowledged); } @Test //删除 public void deleteIndex() throws IOException { //1.创建请求语义对象(本次访问es要做什么操作) DeleteIndexRequest request = new DeleteIndexRequest("test2"); //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 AcknowledgedResponse deleteIndexResponse = esClient.indices().delete(request, RequestOptions.DEFAULT); //3.处理结果信息 boolean acknowledged = deleteIndexResponse.isAcknowledged(); System.out.println(acknowledged); } @Test //查看索引是否存在 public void isOK() throws IOException { //1.创建请求语义对象(本次访问es要做什么操作) GetIndexRequest request = new GetIndexRequest("test2"); //2.发送请求给ES // RequestOptions.DEFAULT: 使用默认的请求方式 boolean exists = esClient.indices().exists(request, RequestOptions.DEFAULT); //3.处理结果信息 System.out.println(exists); } }
文档操作
准备工作
application.yml
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/wind_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 logging: level: root: info
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.example</groupId> <artifactId>WindTest</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.wind</groupId> <artifactId>es</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- mp依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <!-- 解析json--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.32</version> </dependency> <!-- 减少重复代码插件--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
package com.wind.es; import com.alibaba.fastjson.JSON; import com.wind.domain.TestIndex; import com.wind.service.TestIndexService; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import java.io.IOException; import java.util.List; @SpringBootTest public class DocTest { @Resource private RestHighLevelClient client; @Resource private TestIndexService service; /** * //1.创建请求语义对象(本次访问es要做什么操作) * // 设置请求携带的参数 * //2.发送请求给ES * // RequestOptions.DEFAULT: 使用默认的请求方式 * * //3.处理结果信息 * * todo: * java代码操作es中的文档数据 * 添加文档数据 * 查看文档数据 * 删除文档数据 * 修改文档数据 * for批量插入 * bulk批量插入 * 6zMByYoBwd3FfZ8R_WG4 */ @Test //添加文档数据 public void insertDoc() throws IOException { //创建请求语义对象 IndexRequest request = new IndexRequest("test"); //构建参数 String jsonString = "{" + "\"name\":\"奶茶妹\"," + "\"age\":\"18\"," + "\"gender\":\"男\"," + "\"email\":\"fengqi@163.com\"" + "}"; TestIndex testIndex = new TestIndex(); testIndex.setName("风起"); testIndex.setAge(18); String s = JSON.toJSONString(testIndex); request.source(testIndex, XContentType.JSON); //发送请求 IndexResponse response = client.index(request, RequestOptions.DEFAULT); //解析返回结果 System.out.println(response.status()); System.out.println(response.getResult()); } @Test //根据id查看文档 public void getIndexDoc() throws IOException { //创建请求语义对象 GetRequest request = new GetRequest( "test", "5DOHyIoBwd3FfZ8Rp2Gv"); //发送请求 GetResponse response = client.get(request, RequestOptions.DEFAULT); String sourceAsString = response.getSourceAsString(); System.out.println(sourceAsString); TestIndex testIndex = JSON.parseObject(sourceAsString, TestIndex.class); System.out.printf("---------------------"); System.out.println(testIndex); } //修改 @Test public void updateDoc() throws IOException { //创建请求语义对象 UpdateRequest request = new UpdateRequest("test","5DOHyIoBwd3FfZ8Rp2Gv"); //构建参数 TestIndex testIndex = new TestIndex(); testIndex.setName("吴彦祖"); testIndex.setAge(111); testIndex.setGender("男"); testIndex.setEmail("吴彦祖163.com"); String jsonString = "{" + "\"name\":\"奶茶妹\"," + "\"age\":\"18\"," + "\"gender\":\"男\"," + "\"email\":\"fengqi@163.com\"" + "}"; request.doc(jsonString,XContentType.JSON); //发送请求 UpdateResponse response = client.update(request, RequestOptions.DEFAULT); System.out.println(response.status()); } //删除 @Test public void delDoc() throws IOException { //创建请求语义对象 DeleteRequest request = new DeleteRequest("test", "5DOHyIoBwd3FfZ8Rp2Gv"); //发送请求给es DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT); //解析返回结果 System.out.println(delete.status()); } @Test //基于for循环的批量插入 public void insertListDoc() throws IOException { List<TestIndex> list = service.list(); for (TestIndex testIndex : list) { //创建语义对象 IndexRequest request = new IndexRequest("test"); //构建参数 request.id(testIndex.getId()+""); request.source(JSON.toJSONString(testIndex),XContentType.JSON); //向es发送请求 IndexResponse response = client.index(request, RequestOptions.DEFAULT); //解析结果 System.out.println(response.status()); } } @Test public void BulkDoc() throws IOException { //创建请求语义对象 BulkRequest bulkRequest = new BulkRequest("test"); //mysql中获取数据 List<TestIndex> list = service.list(); for (TestIndex testIndex : list) { //创建请求语义对象 IndexRequest request = new IndexRequest(); //构建参数 request.source(JSON.toJSONString(testIndex), XContentType.JSON); //添加到bulk处理中 bulkRequest.add(request); } //向es发送请求 BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT); System.out.println(bulk.status()); } }