ES的入门学习

一、开场白

1、哪些人需要学习ES

  • 开发

  • 测试

  • 运维

  • 利用数据来分析和查询的人

作为一个非关系型数据库,有着和mysql关系型数据库一样重要的地位。

2、学习ES需要具备什么基础

  • 会写SQL语句

  • json格式

  • http请求

3、入门学习ES的内容

1)动手操作安装起来,最新的ES版本已经是7.4.2了。

官网https://www.elastic.co/cn/downloads/elasticsearch下载适合你OS版本的程序,解压缩并启动即可。

image.png

2)基于head插件或kibana的操作

3)简单理解为什么ES如此受欢迎,能够支持亿级数据。

4)ES是怎么支持关键词查询的

二、ES的几个知识点

1、和mysql的对比

数据库字段DDL
mysqlDatabaseTableRowColumncreate table
ESIndex 索引Type 类型Document 文档Field 字段Mapping
客户端工具复制方式
mysqlnavicat, SQLyog, MySQL Workbench主从
ESelasticsearch-head, Kibana, Elasticsearch-sql, Elasticsearch-HQ对等

es在5.x以后,没有了string类型,被拆分为关键词搜索keyword和全文搜索text。

keywordtext
自动分词
支持聚合

ES支持多种数据类型,除了上面说的字符串类型,还有日期,布尔,二进制,还有geo,IP,Multi-fields等实用的类型。

2、集群、节点、分片、副本

1)集群与节点

集群一般要有3个节点,分开主分片和副本。

2)节点与分片

节点按角色可分为数据节点、主节点、协同节点。

分片数 = 节点数的1.5 ~ 3倍

3)分片与副本

副本是可以随时调整的,但分片指定后不可变。一般,一个分片有1~2个副本即可保证高可用。

请问下面的这个集群,有多少节点,多少分片,多少主分片,多少副本???

image

注意:集群下的分片数 = 索引的主分片数 * (1 + 副本数)

200GB的数据建议分片数为7~8个。(ES JVM heap 最大可以设置32G 。 30G heap 大概能处理的数据量 10 T。)

集群的状态说明
yellow所有主分片可用,但不是所有副本分片都可用。或者,硬盘空间超过85%
green所有的主分片和副本分片都可用
red部分主分片不可用

在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。开发环境单节点的情况下,由于es默认是有1个副本,主分片和副本不能在同一个节点上,所以副本就是未分配unassigned。新建索引像下面这样建立:

{
 "settings":{
 "number_of_shards":1, 
 "number_of_replicas":0
 }
}

3、倒排索引

注意:不需要索引的字段,一定要明确定义出来,因为默认是自动创建索引的。

@Field(type = FieldType.text , index = FieldIndex.not_analyzed)
private String message;

比如有一个表User

IDNameAgeSex
1Tom18Male
2Kate18Female
3Jack19Male

ES分别为每个field都建立一个倒排索引

TermPosting List ( 存储所有符合term的文档id)
18[1,2]
19[3]

现在的问题是如何快速查找到某个Term?

image

1)提高查询效率,mysql的B+树通过减少磁盘寻道次数,ES直接通过内存查找Term,不读磁盘。

但是如果Term太多,Term Dictionary也会很大,导致内存放不下。

2)于是就有了Term Index,就像字典里的索引页一样,A开头的有哪些term,分别在哪页,可以理解term index是一颗树。通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找。

image

注意:这棵树不会包含所有的term,它包含的是term的一些前缀。

3)把term index缓存到内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘随机读的次数。

(这里遗留一个问题,如果Term Index树还是很大怎么办?)

4、分词器

注意:对于String类型的字段,不需要analysis的也需要明确定义出来,因为默认是会analysis的。

@Field(type = FieldType.keyword)
private String message;

分词是将文本转换成一系列单词(Term or Token)的过程,也可以叫文本分析,在ES里面称为Analysis

@Field(type = FieldType.keyword ,analyzer = "ik_smart", searchAnalyzer = "ik_smart")
private String name;

分词器,推荐支持中文的ik-analyzer,详情参考Elasticsearch 默认分词器和中分分词器之间的比较及使用方法

5、压缩技巧

1)term index:用确定无环状态转换器(Deterministic acyclic finite state transducer, FST)压缩,以字节的方式存储所有的term。

(FST压缩率一般在3倍~20倍之间,相对于TreeMap/HashMap的膨胀3倍,内存节省就有9倍到60倍!)

我们对“october”,“november”, ”december”这三个词构建确定无环有限状态接收机(Deterministric acyclic finite state acceptor, FSA),如下:

image

(TRIE树只共享前缀,而FSA不仅共享前缀还共享后缀。)

我们对“mar”,“jul”,“jun”这三个词构建FST,如下:

image

(FST保证了不同的转移有唯一的值:mar的值为3,jul的值为7, jun的值为6。)

详细请参考 关于Lucene的词典FST深入剖析

2)posting list:增量编码压缩,将大数变小数,按字节存储。

Frame Of Reference压缩算法:

image

3)内存缓存数据:Roaring bitmaps,高效压缩解压和逻辑运算。

Bitmap是一种数据结构,假设有某个posting list:[1,3,4,7,10] 对应的bitmap就是:[1,0,1,1,0,0,1,0,0,1]

Bitmap的缺点是存储空间随着文档个数线性增长,

Roaring bitmaps需要打破这个魔咒就一定要用到某些指数特性:将posting list按照65535(=2^16-1,一个short的存储单位)为界限分块,比如第一块所包含的文档id范围在065535之间,第二块的id范围是65536131071,以此类推。再用<商,余数>的组合表示每一组id,这样每组里的id范围都在0~65535内了。

image

If a block has more than 4096 values, encode as a bit set, and otherwise as a simple array using 2 bytes per value

6、记得给索引取别名

巧妙利用这点,在你想修改某个字段的类型,或删除某个字段的时候,而不想修改代码的时候,作用就很明显了。当你的存储数据是基于时间序列规则的时候,你只要使用别名查询,ES会自动聚合。

image.png

好处是代码使用别名,只要别名一致,无论ES这么折腾,不会让你去修改代码。

三、文档的CRUD

ES提供了一套对外的restful api接口,让你操作变得规范和易懂。

详见官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.1/docs.html

image.png
操作类型普通请求批量操作
查询_search + GET_mget + GET
新增_create + PUT_reindex + POST
删除DELETE_delete_by_query + POST
修改_update + POST_update_by_query + POST

1、创建索引

1)head插件:

开发环境地址: http://192.168.5.57:9100/

image.png
image.png

如果是单节点,非集群环境下,可以像下面这样设置作为测试:

image.png
image.png

新建成功后,可以在概览界面看到刚创建的索引user:

image.png

选择”动作“--》”删除“,在弹出框输入字符”删除"确认,便可以删除user索引。

image.png

看到如下弹出框,说明删除成功!!

image.png

2)postman

注意:请求方式是PUT,请求URL是http://192.168.5.57:9200/user , user是要创建的索引名。

image.png

删除索引,选择请求方式为DELETE

image.png

3)curl 等工具

curl -X PUT 'http://192.168.5.57:9200/user'
​
curl -X DELETE 'http://192.168.5.57:9200/user'

4)head自带的http请求,理解这一点很重要,后面数据的查询和增删改,通过这点都能实现。

创建索引

image.png

删除索引

image.png

2、查询数据

1)简单查询

它只能做查询搜索,不能创建、修改和删除数据,如果想要执行这些操作,那就只能用下一个功能块“复合查询”了。

索引reader有98个document,也就是我们说的98条记录,id字段是主键。

image.png

返回格式,你也可以选择json和csv格式:

image.png

下面是csv格式,支持导出。(亮点哦,建议我们所有的数据分析,打印的数据格式都是csv)

image.png

这里虽然说是基本查询,其实是支持多条件的查询了,类似navicat的查询。所以有必要再讲下使用。

  • must 返回的文档必须满足must子句的条件,类似于 == and

  • must not返回的文档必须不满足must not 子句的条件 类似于!= not

  • should 返回的文档只要满足should中的一个条件即可 类似于 || or

参数含义:

查询参数含义
term相当
wildcard通配符查询 例:* 商品 *
prefix前缀
fuzzy区间,分词模糊查询 结合max_expansions 和min_similarity,数值则表示在此数值的增加,减小数量在多少范围之内的数据;字符则为在此自负基础上增加/减少多少字符范围内的数据
range区间查询,如果type是时间类型,可用内置now表示当前,-1d/h/m/s来进行时间操作
query_string可以对int, long, string查询,对int,long只能本身查询,对string进行分词和本身查询
text片段
missing返回没有字段或值为null的文档

另外:gt/lt/gte/lte就不解释了。

postman查询:地址http://192.168.5.57:9200/user/_search ,请求方式是GET,多条件查询建议使用上面的head。

image.png

如果你是指定id查询,末尾就不需要加_search了。否则会报错

No handler found for uri [/user/collect/3/_search] and method [GET]

image.png
2)复杂查询

相当于postman了,支持发送RESTful API到elasticsearch服务执行。

注意:勾选”易读“,对json文本进行格式化。复杂查询就不单是查询了,还支持增删改。

image.png

3、新增数据

1)指定index的type和id:

image.png

可以看到新增了一条记录。。。

image.png
image.png

上面是id指定,也可以让ES自动生成,但是不建议使用自增的方式插入数据:

image.png

这里大家可能会有疑问,user我知道是索引,那collect是啥子呢,是我们定义的type了,也就是表名。es是非关系型数据库,好处就是灵活。你可以自定义_type。

image.png
方便大家测试,我将user的属性json文本拷贝出来,仅供参考:
​
{
 "name": "测试12",
 "age": "18",
 "gender": "male",
 "ctime": "",
 "utime": ""
}

ES索引的field是很灵活的,不用管总共有哪些field,只写你所需要的就好。

{
 "name": "测试14",
 "gender": "male"
}

当然也可以使用postman等工具哈,归功于ES对外很好的restful api接口。

image.png

4、修改数据

根据主键的唯一性,进行覆写操作。

请求地址为http://192.168.5.57:9200/reader/collect/47/ , 格式是http://192.168.5.57:9200/<_index>/<_type>/<_id> , 操作类型是_update(指明是修改操作),http请求方式是POST。

postman工具,请求地址是http://192.168.5.57:9200/user/collect/4/_update , 请求方式还是post

{ 
 "doc":{
 "name": "测试4"
 }
}

支持条件修改:

请求地址是:http://192.168.5.57:9200/user/_update_by_query/ ,请求方式是POST。

{
 "query": {
 "match": {
 "name": "zhangsan"
 }
 }
}

5、删除数据

请求地址为http://192.168.5.57:9200/user/collect/AW6g18C-QJexQIWLsAxW/ 格式是http://192.168.5.57:9200/<_index>/<_type>/<_id> ,http请求方式是DELETE。

支持条件删除:

请求地址是:http://192.168.5.57:9200/user/_delete_by_query/请求方式是POST

query如何来,建议从head的简单查询视图里拷贝。

{
 "query": {
 "match": {
 "name": "zhangsan"
 }
 }
}

四、Mapping

个人理解这个类似于mysql的DDL语句,上面讲述的crud是属于DML语句。为什么说类似,而不完全是呢?mysql修改一个字段的类型轻轻松,ES会让你的工作绕一大圈子!!

1、查看mapping

在创建索引的时候,一起定义映射:

请求地址:http://192.168.5.57:9200/user ,请求方式PUT。

{
 "settings":{
 "index":{
 "number_of_shards":1,
 "number_of_replicas":0
 }
 },
 "mappings":{
 "collect":{
 "properties":{
 "name":{
 "type":"text"
 },
 "age":{
 "type":"long"
 },
 "gender":{
 "type":"keyword"
 },
 "message":{
 "type":"text",
 "index":"not_analyzed"
 },
 "ctime":{
 "type":"long"
 },
 "utime":{
 "type":"long"
 }
 }
 }
 }
}

查看mapping

请求地址:http://192.168.5.57:9200/user/_mapping/, 请求方式GET

image.png
image.png

2、新增mapping:

请求地址是http://192.168.5.57:9200/user/collect/_mapping ,主要要指定index和type。

image.png

3、修改mapping

准确的说,是新增字段,而不是修改原有的字段类型。如果你需要修改,怎么办?要么删除索引重新导入,要么reindex。有时候请想下新增字段是不是能够解决你的需求~~请参考https://www.cnblogs.com/royfans/p/11436395.html

postman操作:

image.png

head操作:

image.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天草二十六_简村人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值