Elasticsearch学习
Table of Contents
1. 前览
Elasticsearch 7.*版本
Elasticsearch是什么
Elasticsearch是一个实时的分布式全文搜索引擎,可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。 Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
Elasticsearch历史
REST: 表现层状态转换(英语:Representational State Transfer,缩写:REST)是Roy Thomas Fielding 博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息,是风格而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件。
RESTful API是符合REST设计风格的Web API,它从以下三个方面资源进行定义:
- 直观简短的资源地址:URI,比如:
http://example.com/resources
- 传输的资源:Web服务接受与返回的互联网媒体类型,比如:JSON,XML,YAML等。
- 对资源的操作:Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)
-
创建过程
Lucene是开源的、ES的前生
- Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
- ES是基于Lucene,对其进行封装,通过简单的RESTful API来隐藏Lucene的复杂性,从而使得全文搜索变得简单。
对比三家
-
Lucene是apache开放源代码的全文检索引擎工具包,是一个java信息检索程序库,但是比较复杂。
-
Elasticsearch实时的分布式搜索和分析引擎。全文搜索、结构化搜索、分析;
-
Solr同样也是基于Lucene的全文搜索服务器。
-
ES与Solr的选择:
- 单纯的对已有数据进行搜索时,Solr更快
- 当实时建立索引时,Solr会产生IO阻塞,查询性能较差,ES具有明显优势
- 随着数据量的增加,Solr的搜索效率会变得更低,而ES却没有明显的变化
2. Elasticsearch安装
下载安装
https://www.elastic.co/ 官网下载解压即可
我选择了7.12.1版本,与我项目的spring boot版本对应。解压即可。
安装文件目录
|
|
启动ES,在命令行看到9200端口字样就说明已经启动了,可以访问该端口,会得到以下的结果。我的集群名字重新配置过,设置为了nowcoder,默认的情况下集群名是Elasticsearch。说明已经安装好了ES。
3. Elasticsearch head安装使用
当作数据展示工具!所有的查询都用其他的来做比如:Kibana、postman
elasticsearch-head 是用于监控Elasticsearch状态的客户端插件,包括数据可视化、执行增删改查操作等。安装时需要先安装nodejs。
首先直接在https://github.com/mobz/elasticsearch-head上下载,按照文档进行操作。
在我的电脑上解压后得到如下图
按照上述进行操作。
-
进入elasticsearch-head
-
npm install
-
npm run statrt
由于没有之前将ES关掉了,所以没有连接。重新开启ES,发现点击连接依然无法正常连接,打开浏览器控制台发现没有设置跨域连接。
需要在elasticsearch.yml配置文件中增加两个配置项
1 2
http.cors.enabled: true http.cors.allow-origin: "*"
重新启动ES,可以看到已经正常连接了nowcoder
4. Kibana安装
Kibana可以将elasticsearch的数据的通过友好的页面展示出来,提供实时分析的功能。
安装很简单,不演示。
5. ES核心概念
elasticsearch是面向文档、关系型数据库和elasticsearch的对比。ES一切都是JSON!
Relational DB | Elasticsearch |
---|---|
Database(数据库) | Index |
Table(表) | Type(将要弃用) |
Row(行) | Document |
Col(列) | Field |
-
Cluster 集群
通用的集群概念。一个集群由一个唯一的名字标识,默认为“elasticsearch”。集群名称非常重要,具有相同集群名的节点才会组成一个集群。集群名称可以在配置文件中指定。
-
Node 节点
形成集群的每个服务器称为节点。
-
Shard 分片
当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。 当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。
-
Replication 副本、备份
一个分片可以有多个备份(副本)
6. ES常用操作
索引的操作
-
创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14
PUT /person { "settings": { "number_of_replicas": 1, "number_of_shards": 5 } } PUT /person2/_doc/1 { "name":"like", "age": 20, "time": "1993-02-12" }
-
指定字段类型mapping
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/mapping-types.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
字符串类型string: text: 一般被用于全文检索; 将当前Field进行分词 keyword: 当前Field不会被分词 数值类型Numeric: long; integer: short: byte: double: float: half_float: 精度比float小一半 scaled_float: 根据一个long和scaled来表达一个浮点型, long-345, scaled-100->3.45 时间类型Date: date: 针对时间类型指定具体的格式 布尔类型: boolean类型, 表达true和false 二进制类型: binary类型暂时支持Base64 encode string 范围类型: long_range: 赋值时, 无序指定具体的内容, 只需要存储一个范围即可, 指定gt, lt, gte, lte integer_range: 同上 double_range: 同上 float_range: 同上 data_range: 同上 ip_range: 同上 经纬度类型: geo_point: 用来存储经纬度的 ip类型 ip: 可以存储IPV4或IPV6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
PUT /book { "mappings": { "properties": { "name":{ "type":"text", "analyzer": "ik_max_word", "index":true, "store":false }, "author": { "type":"keyword" }, "count":{ "type":"long" }, "descr":{ "type":"text", "analyzer":"ik_max_word" } } } }
-
ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。
-
ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。
-
-
查看
1
GET /person3
-
删除
1
DELETE /person
文档的基本操作
-
新建文档
1 2 3 4 5 6 7
POST /book/_doc { "name": "shuxue", "author": "zhangsan", "count": 5, "descr": "数学书" }
会自动生成id,但是id号很奇怪,不推荐使用,使用POST也可以指定ID。使用PUT创建
1 2 3 4 5 6 7
PUT /book/_doc/1 { "name": "yingyu", "author": "lisi", "count": 5, "descr": "英语书" }
-
修改文档
1 2 3 4 5 6 7 8
# 添加文档, 手动指定id为1, 覆盖式修改和这个一样 PUT /book/_doc/4 { "name": "yingyu已修改", "author": "lisi", "count": 4, "descr": "英语书" }
使用覆盖操作会丢失数据
1 2 3 4 5 6
POST /book/_update/4 { "doc": { "count": 10 } }
-
删除文档
1
DELETE /book/_doc/2
-
简单查询文档
1 2
# 根据id来做简单查 GET /book/_doc/1
7. 集成SpringBoot
主要要参看官方文档
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/java-rest-high-create-index.html
-
导入依赖(注意对应的版本)
1 2 3 4
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
-
配置对象
需要注入一个Bean
1 2 3 4 5 6 7 8 9 10 11 12 13
@Configuration public class ElasticSearchClientConfig { @Bean public RestHighLevelClient restHighLevelClient() { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http") ) ); return client; } }
-
测试
编写测试类
创建索引操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class ElasticsearchTest { @Autowired private RestHighLevelClient restHighLevelClient; @Test public void testCreateIndex() { CreateIndexRequest request = new CreateIndexRequest("test_index"); try { CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT); System.out.println(createIndexResponse); } catch (IOException e) { e.printStackTrace(); } } }