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. 5.ElasticSearch系列之文档的基本操作

    1. 文档写入 # create document. 自动生成 _id POST users/_doc { "user" : "shenjian", " ...

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

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

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

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

随机推荐

  1. JavaWeb——EL及JSTL学习总结

    什么是EL表达式 为什么需要EL EL的主要作用 EL的语法 EL的开发步骤 EL实例练习 EL中的运算符 EL表达式显示内容的特点 EL的特点 EL隐式对象 EL隐式对象介绍 隐式对象实例练习 什么 ...

  2. Fastjson使用实例

    Fastjson使用实例 一.FastJson使用范例 1.1FastJson三个核心类 1.2Maven依赖 1.3Scala API 1.3.1反序列化 1.3.2序列化 1.4Java API ...

  3. 面向对象编程(UDP协议)

    UDP协议 UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无 ...

  4. 函数式编程(hashlib模块)

      hashlib模块 一.hashlib模块 hashlib模块,主要用于加密相关的操作,在python3的版本里,代替了md5和sha模块,主要提供 SHA1, SHA224, SHA256, S ...

  5. vim自动添加C C++ sh文件头

    set foldenable set foldmethod=manual set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 set ...

  6. 我们到底为什么要用 IoC 和 AOP

    作为一名 Java 开发,对 Spring 框架是再熟悉不过的了.Spring 支持的控制反转(Inversion of Control,缩写为IoC)和面向切面编程(Aspect-oriented ...

  7. Effective Java读书笔记--对所有对象都通用的方法

    1.覆盖equals请遵守通用规定.不需要覆写equals的场景:a.类的每个实例都是唯一的.b.类不需要提供"逻辑相等"的测试功能.c.超类已经覆盖了equals的方法.d.类是 ...

  8. codeforces628D. Magic Numbers (数位dp)

    Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in d ...

  9. Cyclic Nacklace HDU - 3746

    CC这个月底总是很郁闷,昨天他查了他的信用卡,没有任何意外,只剩下99.9元了.他很苦恼,想着如何度过这最后的几天.受"HDU CakeMan"企业家精神的启发,他想卖一些小东西来 ...

  10. linux 部署 .net core mvc

    1.本地编写一个mvc网站 代码编辑器:Visual studio 2017.2019.Visual Code 均可 1)搭建 略. (请自行搜索如何编辑mvc,或看文末参考链接) 2)配置 Prog ...