Elasticsearch简介、倒排索引、文档基本操作、分词器
lucene、Solr、Elasticsearch
1、倒排序索引
2、Lucene是类库
3、solr基于lucene
4、ES基于lucene
一、Elasticsearch 核心术语
特点:
1、es可以支持空格查询,多个关键字
2、空格支持
3、拆词查询
4、搜索内容可以高亮
5、海量数据查库
ES 可以对照着 数据库 来理解:
- 索引index --------> 表
- 文档 document --------> 行(记录)
- 字段 fields --------> 列
Elasticsearch的存储形式:
stu_index { id: 1001, name: jason, age: 19 }, { id: 1002, name: tom, age: 18 }, { id: 1003, name: rose, age: 22 }
集群相关
- 分片(shard):把索引库拆分为多份,分别放在不同的节点上,比如有3个节点,3个节点的所有数据内容加在一起是一个完整的索引库。分别保存到三个节点上,目的为了水平扩展,提高吞吐量。
- 备份(replica):每个shard的备份。
简称
shard = primary shard(主分片)
replica = replica shard(备份节点)
二、ES集群架构原理
加入有3TB的数据那么ES向上面的架构模型,每个shard会承担1TB的数据,当一个ES的shard出现故障,那么它的replica就会成为它的角色。
shard和replica机制
A、index包含多个shard
B、每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整地建立索引和处理请求的能力
C、增加或减少节点时,shard会自动地在node中负载均衡
D、primary shard和replica shard,每个document肯定只存在于某一个primary shard以及其对应的replica shard 中,不可能存在于多个primary shard
E、replica shard是primary shard 的副本,负责容错以及承担读请求负载
F、primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
G、primary shard不能和自己的replica shard放在同一节点上,但是可以和其它primary shard放在同一节点上
三、倒排索引
ES为什么这么快?
1、索引方式的区别,es主要是利用倒排索引(inverted index),这个翻译可能会让初次接触的人产生误解,误以为是倒着排序?其实不是这样,一般关系型数据库索引是把某个字段建立起一张索引表,传入这个字段的某个值,再去索引中判断是否有这个值,从而找到这个值所在数据(id)的位置。而倒排索引则是把这个值所在的文档id记录下来,当输入这个值的时候,直接查询出这个值所匹配的文档id,再取出id。所以我们在建立es索引的时候,有分词的概念,相当于可以把filed字段内容拆分,然后索引记录下来。例如“我爱中国”,可以拆分成“我”,“爱”,“中国”,“我爱中国”这五个词,同时记录下来这几个关键词的对应文档数据id是1,当我们查询“我”,“中国”时,都能查出这条数据。而如果使用关系型数据库去查包含“中国”这个关键字的数据的时候,则需要like前后通配全表扫描,无法快速找到关键词所在的数据行。
2、倒排索引是不可更改的,一旦它被建立了,里面的数据就不会再进行更改。这样做就带来了以下几个好处:
- 不用给索引加锁,因为不允许被更改,只有读操作,所以就不用考虑多线程导致互斥等问题。
- 索引一旦被加载到了缓存中,大部分访问操作都是对内存的读操作,省去了访问磁盘带来的io开销。
- 倒排索引具有不可变性,所有基于该索引而产生的缓存也不需要更改,因为没有数据变更。
- 倒排索引可以压缩数据,减少磁盘io及对内存的消耗。
倒排索引结构:
如图左边为存储结构,右边为倒排索引,将左边的每条文档值内容进行分词并且记录词频和位置,比如我们现在搜索“集群”两字就会直接按照文档ids进行搜索,得到文档1、2、3条记录,搜索“学习”会得到文档1、3两条记录。
四、Elasticsearch安装
1.下载Elasticsearch Linux版安装包
官网下载太慢,直接使用我下载好的安装包
链接:https://pan.baidu.com/s/1Na0K7hIFJbGECD9XCwdR4A
提取码:9oz6
复制这段内容后打开百度网盘手机App,操作更方便哦
2.安装
- 解压
tar -zxvf elasticsearch-7.10.1-linux-x86_64.tar.gz
- 将解压的文件移动到 /usr/local下面
mv elasticsearch-7.10.1 /usr/local
- 进入目录查看
cd /usr/local/elasticsearch-7.10.1 ll
- ES 目录介绍
bin:可执行文件在里面,运行es的命令就在这个里面,包含了一些脚本文件等
config:配置文件目录
JDK:java环境
lib:依赖的jar,类库
logs:日志文件
modules:es相关的模块
plugins:可以自己开发的插件
data:这个目录没有,自己新建一下,后面要用 -> mkdir data,这个作为索引目录
- 修改核心配置文件 elasticearch.yml
- 修改集群名称,默认是elasticsearch,虽然目前是单机,但是也会有默认的
- 为当前的es节点取个名称,名称随意,如果在集群环境中,都要有相应的名字
- 修改data数据保存地址
- 修改日志数据保存地址
5.绑定es网络ip,原理同redis
6.默认端口号9200,可以自定义修改
7.集群节点,名字可以先改成之前的那个节点名称
- 修改JVM参数
默认xms和xmx都是1g,我使用的是虚拟机内存没这么大,修改一下即可
vim jvm.options
- 添加用户
ES不允许使用root操作es,需要添加用户,操作如下:
useradd esuser chown -R esuser:esuser /usr/local/elasticsearch-7.4.2 whoami
- 解决启动保存问题
- 修改 limits.conf 文件
vim /etc/security/limits.conf
在尾部添加如下内容
* soft nofile 65536 * hard nofile 131072 * soft nproc 2048 * hard nproc 4096
2. 修改 sysctl.conf 文件
vim /etc/sysctl.conf
在下面添加如下内容
vm.max_map_count=262145
- 启动
- 切换到刚才创建的用户下
su esuser
2. 到ES的bin目录下面
cd /usr/local/elasticsearch-7.10.1/bin
3.启动
./elasticsearch ## 前台启动
./elasticsearch -d ## 后台启动
- 测试
在浏览器输入 虚拟器IP + ES端口号
9200:Http协议,用于外部通讯
9300:Tcp协议,ES集群之间是通过9300通讯
http://192.168.2.223:9200/
成功
- 安装ES可视化工具ES-Header
github地址:https://github.com/mobz/elasticsearch-head
为方便起见我使用Google插件进行安装,备注:需要能谷歌上网
安装完成后如下所示为用ES-Header查看我们刚才安装后的ES节点信息:
- 解决跨域问题
在 elasticearch.yml 中加入如下内容即可:
http.cors.enabled: true
http.cors.allow-origin: "*"
五、ES文档的基本操作--增删改查
1、增加操作
- 在可视化工具中建一个索引命名为 my_doc
- 手动添加文档数据
http://192.168.2.223:9200/my_doc/_doc/1 { "id": 1001, "name": "zhouhong-1", "desc": "zhouhong is my good fridend!", "create_date": "2021-02-19" } http://192.168.2.223:9200/my_doc/_doc/2 { "id": 1002, "name": "zhouhong-2", "desc": "zhouhong 是一个好人", "create_date": "2021-02-18" } http://192.168.2.223:9200/my_doc/_doc/3 { "id": 1003, "name": "zhouhong-3", "desc": "zhouhong 真的是一个好人", "create_date": "2021-02-18" } http://192.168.2.223:9200/my_doc/_doc/4 { "id": 1004, "name": "zhouhong-4", "desc": "zhouhong is her friend", "create_date": "2021-02-18" } http://192.168.2.223:9200/my_doc/_doc/5 { "id": 1005, "name": "zhouhong-5", "desc": "zhouhong is 好人", "create_date": "2021-02-18" } http://192.168.2.223:9200/my_doc/_doc/6 { "id": 1006, "name": "zhouhong-6", "desc": "zhouhong is realy good man", "create_date": "2021-02-18" }
- 检查是否添加成功
2、删除
3、修改请求
{ "doc": { "name" "周红" } }
4、查询
- 根据文档id查询
{ "_index": "my_doc", "_type": "_doc", "_id": "6", "_version": 2, "_seq_no": 17, "_primary_term": 1, "found": true, "_source": { "id": 1006, "name": "zhouhong-6", "desc": "zhouhong is realy good man", "create_date": "2021-02-18" } }
- 查询所有
- 查询部分数据
- 判断当前索引是否存在文档,以下方式比较规范
六、ES分词器
ES默认只支持英文分词,如果是中文它会拆分为一个一个字
1、默认分词器
a.分词器(会忽略大小写):
- 标准分词器standard(把单词进行分割)
- 简单分词器simple(会去除字符串中非字母的元素)
- 空格分词器whitespace(根据空格进行分割)
- stop(会去除英文语句中的无意义的单词:the 、is、a等等)
- keyword(会将整个文本当作一个词,不会被拆分)
b.标准分词器演示:
{ "analyzer": "standard", "text": "zhouhong is a good man!" }
{ "tokens": [ { "token": "zhouhong", "start_offset": 0, "end_offset": 8, "type": "<ALPHANUM>", "position": 0 }, { "token": "is", "start_offset": 9, "end_offset": 11, "type": "<ALPHANUM>", "position": 1 }, { "token": "a", "start_offset": 12, "end_offset": 13, "type": "<ALPHANUM>", "position": 2 }, { "token": "good", "start_offset": 14, "end_offset": 18, "type": "<ALPHANUM>", "position": 3 }, { "token": "man", "start_offset": 19, "end_offset": 22, "type": "<ALPHANUM>", "position": 4 } ] }
2、IK中文分词器
1.安装
- 将压缩包解压到ES下的 plugins 下
unzip elasticsearch-analysis-ik-7.10.1.zip -d /usr/local/elasticsearch-7.10.1/plugins/ik
2.测试
- 使用 ik_max_word(最细粒的拆分) 测试
{ "analyzer": "ik_max_word", "text": "明天早上吃什么呢" }
{ "tokens": [ { "token": "明天", "start_offset": 0, "end_offset": 2, "type": "CN_WORD", "position": 0 }, { "token": "早上", "start_offset": 2, "end_offset": 4, "type": "CN_WORD", "position": 1 }, { "token": "吃什么", "start_offset": 4, "end_offset": 7, "type": "CN_WORD", "position": 2 }, { "token": "什么", "start_offset": 5, "end_offset": 7, "type": "CN_WORD", "position": 3 }, { "token": "呢", "start_offset": 7, "end_offset": 8, "type": "CN_CHAR", "position": 4 } ] }
- 使用 ik_smart 分词器测试
{ "analyzer": "ik_smart", "text": "明天早上吃什么呢" }
{ "tokens": [ { "token": "明天", "start_offset": 0, "end_offset": 2, "type": "CN_WORD", "position": 0 }, { "token": "早上", "start_offset": 2, "end_offset": 4, "type": "CN_WORD", "position": 1 }, { "token": "吃什么", "start_offset": 4, "end_offset": 7, "type": "CN_WORD", "position": 2 }, { "token": "呢", "start_offset": 7, "end_offset": 8, "type": "CN_CHAR", "position": 3 } ] }
3、自定义中文分词器
{ "analyzer": "ik_max_word", "text": "周红" } { "tokens": [ { "token": "周", "start_offset": 0, "end_offset": 1, "type": "CN_CHAR", "position": 0 }, { "token": "红", "start_offset": 1, "end_offset": 2, "type": "CN_CHAR", "position": 1 } ] }
- 在IK分词器安装目录下面的配置文件,增加一个custom.dic的字典文件
vim /usr/local/elasticsearch-7.10.1/plugins/ik/config/IKAnalyzer.cfg.xml
- 在同级目录下新建一个custom.dic文件里面写上我们不需要拆分的词
- 测试
{ "analyzer": "ik_max_word", "text": "周红" }
{ "tokens": [ { "token": "周红", "start_offset": 0, "end_offset": 2, "type": "CN_WORD", "position": 0 } ] }
后面如果想扩展,只需在自定义的custom.dic里面添加词汇即可
本文来自博客园,作者:Tom-shushu,转载请注明原文链接:https://www.cnblogs.com/Tom-shushu/p/14428159.html