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
  1. 修改集群名称,默认是elasticsearch,虽然目前是单机,但是也会有默认的
  2. 为当前的es节点取个名称,名称随意,如果在集群环境中,都要有相应的名字
  3. 修改data数据保存地址
  4. 修改日志数据保存地址

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
  • 解决启动保存问题
  1. 修改 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

  • 启动
  1. 切换到刚才创建的用户下
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、增加操作

如果索引没有手动建立mapping,那么插入文档数据时,会根据文档类型自动设置属性类型。这个就是es动态映射,帮我们在index索引库中去建立数据结构的相关配置。
  • 在可视化工具中建一个索引命名为 my_doc

  • 手动添加文档数据
在postman里面发送post请求到http://192.168.2.223:9200/my_doc/_doc/1
注意:my_doc为索引名、_doc为文档类型、1为为文档起的id唯一编号(如果不指定系统会为每条数据自动分配一个)
添加数据:
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、删除

直接调用 http://192.168.2.223:9200/my_doc/_doc/6 发送DELETE请求既可
注意:这里的删除操作不是真正的删除,只是逻辑上的删除(添加标识符)ES属于被动删除,只有在磁盘满了的时候会被动删除。

3、修改请求

直接调用:http://192.168.2.223:9200/my_doc/_doc/6/_update 发送POST请求
入参:
{
"doc": {
"name" "周红"
}
}

4、查询

  • 根据文档id查询
直接发送GET请求http://192.168.2.223:9200/my_doc/_doc/6
相当于:select * from my_doc where _id = 6
结果:
{
"_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"
}
}
_index:文档数据所属那个索引,理解为数据库的某张表即可。
_type:文档数据属于哪个类型,新版本使用_doc。
_id:文档数据的唯一标识,类似数据库中某张表的主键。可以自动生成或者动指定。
_score:查询相关度,是否契合用户匹配,分数越高用户的搜索体验越高。
_version:版本号。
_source:文档数据,json格式。
  • 查询所有
相当于:select * from my_doc
调用 http://192.168.2.223:9200/my_doc/_doc/_search 发送GET请求
  • 查询部分数据
相当于: select id, name from my_doc where _id = 2
GET请求http://192.168.2.223:9200/my_doc/_doc/1?source=id,name
  • 判断当前索引是否存在文档,以下方式比较规范
发送HEAD请求 http://192.168.31.183:9200/my_doc/_doc/2 根据相应状态码HttpStatusCode:200,则存在,404则不存在
比使用GET查询请求判断文档是否存在效率更高

六、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对应的IK压缩包上传服务器
  • 将压缩包解压到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、自定义中文分词器

IK默认分词器虽然很好用,但是会存在一个问题,像我们的网络用语,姓名等等它会分割为一个一个的字不符合我们的需求比如下面这个情况:
{
"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里面添加词汇即可

Elasticsearch简介、倒排索引、文档基本操作、分词器的更多相关文章

  1. Elasticsearch 7.x文档基本操作(CRUD)

    官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html 1.添加文档 1.1.指定文档ID PUT ...

  2. Linux下,非Docker启动Elasticsearch 6.3.0,安装ik分词器插件,以及使用Kibana测试Elasticsearch,

    Linux下,非Docker启动Elasticsearch 6.3.0 查看java版本,需要1.8版本 java -version yum -y install java 创建用户,因为elasti ...

  3. Elasticsearch之几个重要的分词器

    前提 什么是倒排索引? Elasticsearch之分词器的作用 Elasticsearch之分词器的工作流程 Elasticsearch之停用词 Elasticsearch之中文分词器 Elasti ...

  4. Elasticsearch从入门到放弃:分词器初印象

    Elasticsearch 系列回来了,先给因为这个系列关注我的同学说声抱歉,拖了这么久才回来,这个系列虽然叫「Elasticsearch 从入门到放弃」,但只有三篇就放弃还是有点过分的,所以还是回来 ...

  5. ElasticSearch(三):通分词器(Analyzer)进行分词(Analysis)

    ElasticSearch(三):通过分词器(Analyzer)进行分词(Analysis) 学习课程链接<Elasticsearch核心技术与实战> Analysis与Analyzer ...

  6. C#开源组件DocX处理Word文档基本操作(二)

    上一篇 C#开源组件DocX处理Word文档基本操作(一) 介绍了DocX的段落.表格及图片的处理,本篇介绍页眉页脚的处理. 示例代码所用DocX版本为:1.3.0.0.关于版本的区别,请参见上篇,而 ...

  7. ElasticSearch High Level REST API【1】文档基本操作

    获取ES客户端 ES的提供了四种Java客户端,分别为节点客户端(node client).传输客户端(Transport Client).低级REST客户端.高级REST客户端. 节点客户端作为集群 ...

  8. ElasticSearch(四)查询、分词器

    正向索引 正排表是以文档的ID为关键字,表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档. 这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于 ...

  9. Elasticsearch操作Document文档

    1.利用客户端操作Document文档数据        1.1 创建一个文档(创建数据的过程,向表中去添加数据)            请求方式:Post    请求地址:es所在IP:9200/索 ...

  10. 关于Elasticsearch单个索引文档最大数量问题

    因为ElasticSearch是一个基于Lucene的搜索服务器.Lucene的索引有个难以克服的限制,导致Elasticsearch的单个分片存在最大文档数量限制,一个索引分片的最大文档数量是20亿 ...

随机推荐

  1. 关于java中的MANIFEST.MF 文件内容

    打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息.可以简化Java应用程 ...

  2. MySQL表字段长度的限制

    在MySQL建表时,遇到一个奇怪的现象: root::>CREATE TABLE tb_test ( ) NOT NULL, ) DEFAULT NULL, ) DEFAULT NULL, ) ...

  3. IDE-Sublime【1】-JsFormat插件格式化缩进问题

    JsFormat插件格式化Javascript代码的快捷键是ctrl+alt+f,发现默认缩进2个空格,但习惯上是4个空格,这里需要手动设置一下. 操作步骤: 1.打开Preferences-> ...

  4. javascript------&gt;(此文转发)

    JS控制div跳转到指定的位置的解决方案总结   总结一下自己在写这个需求遇到的问题,相信大家应该是经常遇到的.即要求滚轮滚动到指定的位置.先看下基本的解决方案. 1.给链接a加个#的方式来实现跳转. ...

  5. oracle 复制一条记录只改变主键不写全部列名

    场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...

  6. Linux之shell编程基础

    一.变量 变量在shell中分为:本地变量.环境变量.位置参数: 本地变量:仅可在用户当前shell生命期的脚本中使用的变量,本地变量随着shell进程的消亡而无效,本地变量在新启动的shell中依旧 ...

  7. ZOJ 1403&amp;&amp;HDU 1015 Safecracker【暴力】

    Safecracker Time Limit: 2 Seconds      Memory Limit: 65536 KB === Op tech briefing, 2002/11/02 06:42 ...

  8. 浅谈C之精华---指针

    今天是2016年的第一天,祝大家元旦快乐!哎,今天有点倒霉,代码写到一半,突然机子就没电了,幸好有保存,否则今天没有这篇日志的出现. 好了,今天以我个人的角度来深度剖析一下C语言中关于指针的用法以及注 ...

  9. Cesium 绘制点、线、面和测距

    本文基于ES6,采用React+Cesium的Webgis前端开发框架,目前threejs和cesium的结合正在研究中.此段代码采用原生javascript,可能过程中用到了es6的扁平化语法,如( ...

  10. Linux基本命令大全

    linux的基本命令 增 mKdir test # 创建一个名为test的文件夹 mkdir -p test1/test2/test3 # 递归创建directory mkdir -p {aaa,bb ...