ElasticSearch教学篇
续上前言
所有有关于ElasticSearch的文档我想连在一起更新完在更新其他的内容,这篇主要是讲解如何使用restful风格去操作ElasticSearch,因为像我上篇所说直接写一篇SpringBoot集合ElasticSearch的可能内容会有点多,大家也是会看的有点吃亏,那么我就不定时给大家更新完,也让大家有一个消化期,从这篇开始我会将之前的博文路径都以表单的方式放入下面,大家可以直接跳转即可
名称 | 路径 |
---|---|
ES搜索(ElasticSearch)入门理论篇 | 点击进入 |
ES搜索、Head、Kibana安装使用篇 | 点击进入 |
下面我们续着上一章内容继续,在上面我们是把ES搜索、ElasticSearch Head、Kibana都安装好了,那么我们怎么去操作ES呢,之前只是说了一些安装一些工具,下面我来说一下具体的实现思路
ES核心
我在讲解实战之前再给大家唠嗑一下,然后等下还需要安装一样工具,我会把安装思路告知大家!
ElaticSearch是面向文档的 关系行数据库和ElaticSearch客观的对比
ElaticSearch(集群)可以包含多个索引(数据库),每个索引可以包含多个类(表),每个类下又包含多个文档(行),每个文档又包含多个字段(列)
物理设计
ElaticSearch在后台把每个索引划分成多个分片,每个分片可以在集群中不同服务器间迁移,一个人就是一个集群!默认的集群名称就是ElaticSearch
逻辑设计
一个索引类型中,又包含多个文档,比如说文档a、文档b。当我们索引一篇文档时,可以通过这样的一个顺序找到它:索引>类型>文档>ID,通过这个组合我们就能索引到某个具体的文档。注意:ID不必是整数,实际上它是个字符串
文档(重要)
ElaticSearch本身就是一个文档,那么久说明索引和搜索数据的最小单位就是文档,ElaticSearch中,文档有几个重要属性:
- 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value
- 可以层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
- 灵活的层次结构.文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才可以使用,在ElaticSearch中,对于字段是非常灵活的,有时候,我们可以忽略字段,或者动态的添加一个新字段
- 尽管我们可以随意的新增或者忽略某个字段,但是每个字段的类型都是非常重要,比如一个年龄字段类型,可以是字符串,也可以是整形,因为ElaticSearch会保存字段和类型之间的映射及其他的设置,这种映射到具体每个映射的每种类型,这也是在ElaticSearch中,类型有时候称为映射类型
类型
类型是文档逻辑容器,就像关系型数据库一样,表格是行的容器,类型中对于字段的定义称为映射,比如name映射,为字符串类型,我们说文档是无模式的,他不需要拥有映射中所定义的所有字段,比如说新增一个字段,那么ElaticSearch是怎么做的呢?ElaticSearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型,ElaticSearch就开始猜,如果这个值是18,那么ElaticSearch会认定这个值为整形,但是ElaticSearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库速途同归了,先定义好字段,然后在使用
索引
藤井在这认为索引就是数据库
索引时映射类型的容器,ElaticSearch中的索引就是一个非常大的文档集合,索引存储了映射类型的字段和其他设置,然后在存储到各个分片上,下面来研究一下分片是如何进行工作的
物理设计
分节和分片如何工作
一个集群至少有一个节点,而一个节点就是一个ElaticSearch进程,节点可以有多个索引默认的,如果你创建索引,那么索引会将有5个分片(primary shard,又称主分片)构成的,每一个主分片会有一个副本(replica shard,又称复制分片)
上图是一个有3个节点的集群,可以看到主分片好对应的复制分片都不会在同一个节点内,这样有利于某个节点挂了之后呢,数据也不至于丢失,实际上,一个分片就是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得ElaticSearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字,下面让我们了解一下倒排索引吧
倒排索引
小提示:在现在的发展趋势中,面试官也是比较喜欢问什么是倒排索引哦!
ElaticSearch使用的是一种称为倒排索引的结构,采用Lucene倒排索引作为底层,这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表
ElaticSearch中,索引(库)这个词被频繁使用,这就是术语的使用,在ElaticSearch中,索引被分为多个分片,每个分片是Lucene的索引,所以一个ElaticSearch索引就是由多个Lucene索引组成的。因为ElaticSearch使用Lucene作为底层,说起来还是指ElaticSearch的索引
IK分词器
什么是IK分词器
分词:就是把一段中文或者别的划分为一个个关键字,我们在搜索的时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看做一个词,比如“藤井大叔”分成“藤”,“井”,“大”,“叔”,这明显是不符合要求的,所以就要安装中文分词器IK来解决这个问题
IK提供了两种分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分
安装
注意:7.10.1自带IK分词器,以上版本未知,如没有可根据以下版本去安装下载
安装地址:https://github.com/medcl/elasticsearch-analysis-ik
当我们的版本如果有IK分词器那么你运行cmd会有显示的,可进行查看
命令行查看IK
步骤:打开ES搜索文件夹运行cmd输入命令:elasticsearch-plugin list
好了,这下我们工具齐全,那么就可以开始工作了,在屡一下我们的安装工具,下面我在巩固一下我们所安装的工具,具体安装如下:
- ElasticSearch:直接官网下载,下载可能会有点慢,网速不好下载一天,可用迅雷或其他方式下载,下载即用
- ElasticSearch Head:可在GitHub下载即可,不需要很久,下载即用
- Kibana:直接在官网下载,可能会有点慢,也可用迅雷,下载即用
- IK:7.10.1版本自带,其他版本未知如需下载可在GitHub上下载
注:所有下载方式在上方讲解都有,专心看完
Kibana测试
这里我们就拿我们的祖国名称来做测试“中华人民共和国”
上面我有提到有两种方式首先我们拿第一种测试,也就是: ik_smart
第二种测试方法:ik_max_word
测试成功,观察问题,下面拿我网名测试
这种我们自己需要的值,是需要自己去加入到分词器的字典中,下面看如何进行!
好的下面直接开始试验
上面这个子目录下直接新建了一个藤井大叔的英文名uncletj.dic的文件夹,然后呢在把文件夹名称放入这个子目录下的.xml文件里面,具体操作看如下图
在完成上面操作之后呢,记得重启ES!
注:一定要把.dic文件编码格式设置成utf-8
下面我们来看一下生效了吗?
找到了,证明是成功了,好了,有关于这边的测试就到此结束,下面我们直接实战一下试试?
ResuFul风格
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件,它主要用于客户端和服务器交互类的软件。基于这个风格,设计的软件可以更加简洁,更有层次,更容易实现缓存等机制
基于Rest命令说明
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
POST | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) |
POST | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 查询文档通过文档id |
POST | localhost:9200/索引名称/类型名称/search | 查询所有数据 |
测试
创建一个索引
格式:put /索引名/类型名/
完成了自动增加索引,数据也成功的添加了,这也是我上面说的把它当做数据库的原因
字段常用类型介绍
字符串类型
text、keyword
数值类型
long、integer、short、byte、double、float、half float、scaled float
日期类型
date
布尔值类型
boolean
二进制类型
binary
指定字段类型
创建规则
通过GET请求获取索引信息
查看默认信息
如果你的文档字段没有指定,那么它会默认给你配置字段类型
查看信息命令(GET _cat/…)
GET _cat/health:查看健康值
GET _cat/indices:查看所有索引信息
修改
(1)直接在原来的上面进行修改
(2)使用POST方式修改
删除索引
删除索引全部内容
通过DELETE就可以实现删除了,根据你的删除请求来判断是删除索引还是来删除索引文档记录!
使用RestFul风格是ES推荐使用的!
好了基本操作就是上面这样的,然后我们再来回顾一下,下面来总结一下
基本操作回顾
添加
1.添加一条数据 PUT
PUT /uncletj/user/1
{
"name":"藤井大叔",
"age":23,
"desc":"自信即巅峰",
"tags":["技术宅","温暖","直男"]
}
查询
2.获取数据 GET
更新
3.更新数据 PUT
3.1:POST _update,推荐使用这种更新方式!下面这种灵活性更高
搜索方式
简单搜索
GET uncletj/user/1
简单查询
GET uncletj/user/_search?q=name:藤井
结构式讲解:
GET:查询方式
uncletj/user:所查询的库
_search:查询所有
?q=name:藤井:查询条件
简单的条件查询,可以根据默认的映射规则,产生基本的查询
复杂搜索select(排序、分页、高亮、模糊查询、精准查询)
输出结果,相当于数据库的select 字段名1、字段名2… from 表名
我们之后使用Java操作es,所有的方法和对象就是这里面的key
排序
当然也可以使用下面代码会更规范
GET uncletj/user/_search
{
"query": {
"match": {
"name":"可乐"
}
},
"sort":{
"age":{
"order":"asc"
}
}
}
分页(from:起始页;size:每页的数值数)
布尔值查询
must(and),所有的条件都要符合,同等于数据库的where …and…
其他用法
(1)把must改成should那么就等价与or
(2)把must改成must_not那么就是不等于这个的数据显示,相当于not
过滤
gt:大于
gte:大于等于
lt:小于
lte:小于等于
多个条件进行查询
直接在里面加就好了,上面的意思是大于等于1岁并且小于15岁
匹配多个条件
精确查询
term查询是直接通过倒排索引指定的词条进程精确的查询
关于分词:
term:直接查询精确的
match:会使用分词器解析!(先分析文档,然后在通过分析的文档进行查询)
两个类型text keyword
好了,这篇就到此结束了,内容可能会稍微有些多,我在后期会直接续住这篇来进行下篇的开展,当然这时会有人有缴械心理,我等藤井先把所有的先更新完在一起看完,在这里告诉大家一口吃不了大胖子,如真的想学好那就温故而知新是最好的选择,咱们下期见!