ElasticSearch7.6.x 学习笔记
什么是ElasticSearch,为什么要用它?
ElasticSearch,简称es。es是一个开源的高扩展的分布式全文搜索引擎,它可以近乎实时的存储,检索数据,本身扩展性好,可以扩展到上百台服务器,处理PB级的数据,es也使用java开发并使用Lucene作为核心来实现所有索引和搜索的功能,但是它的目的是通过简单的Restful APL来隐藏Lucene的复杂性,从而使全文检索变得简单。
ElasticSearch在2016年已超过solr,成为排名第一的搜索引擎类应用。像维基百科,百度,GitHub等著名网站的搜索都是由ElasticSearch完成的。
ElasticSearch与solr的区别?
- Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;
- Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;
- Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供;
- Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch
- es是开箱即用,非常简单,solr安装略显复杂;
- solr查询快,但更新索引慢,用于电商等查询多的应用;es建立索引快,即实时查询快,用于facebook等查询;
- solr比较成熟,有一个更大的,更成熟的用户,开发和贡献者社区,es出现晚,目前开发维护这相对较少,更新快,学习成本高。
在这里插入图片描述
安装
es及其相关工具安装十分简单,下载对应系统的压缩包解压即可运行。
(注意es及其相关工具的版本要尽量一致,不然会有很多问题)
es安装
下载压缩包:
ElasticSearch的官方地址: https://www.elastic.co/products/elasticsearch
注意,es默认要占用1g内存,可能会以为内存不够而无法打开,可以在配置文件中修改
打开config下的jvm.options
改成256m,电脑不好的可能要更小。
head插件
ElasticSearch不同于Solr自带图形化界面,我们可以通过安装ElasticSearch的head插件,完成图形化界面的效果,完成索引数据的查看。elasticsearch-5-*以上版本安装head需要安装node和grunt
- 下载head插件:https://github.com/mobz/elasticsearch-head
- 下载node.js:https://nodejs.org/en/download/
双击安装,通过cmd输入 node -v查看版本号
- 将grunt安装为全局命令 ,Grunt是基于Node.js的项目构建工具
在cmd中输入:
npm install ‐g grunt‐cli
- 检测是否安装成功
npm config get registry
- 启动head 进入head插件目录,打开cmd,输入:
>npm install
>grunt server
- 打开浏览器,输入http://localhost:9100即可
ElasticHD 安装
如果觉得head麻烦或者界面丑,可以使用ElasticHD 代替。
- ElasticHD Windows环境下安装
https://github.com/360EntSecGroup-Skylar/ElasticHD
下载压缩包解压,只有一个文件
你以为可以直接运行吗,那你就错了。
打开cmd,输入
cd D:\wed\ElasticHD (这是我文件的目录)
ElasticHD -p 127.0.0.1:9800
连接即可
kibana
Kibana架构为Elasticsearch定制,可以将任何结构化和非结构化数据加入Elasticsearch索引。Kibana还充分利用了Elasticsearch强大的搜索和分析功能,本文主要使用kibana就行讲解。
下载解压安装包,一定要装与ES相同的版本
下载地址: https://www.elastic.co/downloads/kibana
打开"kibana-7.6.1-windows-x86_64\config\kibana.yml"
可以添加一些配置
修改默认端口
elasticsearch.hosts: [“http://118.178.125.139:9200”]
汉化
i18n.locale: “zh-CN”
“kibana-7.6.1-windows-x86_64\bin\kibana.bat”
该文件打开应用
在浏览器输入http://localhost:5601/app/kibana
打开应用时可能比较久,耐心等待
ES核心概念理解
前面的学习中,我们已经掌握了es是什么,同时也将es服务安装启动,那么es是如何去存储数据的呢?数据结构是什么?如何实现搜索?
es是面向文档,关系型数据库与es客观对比
Relational DB | ES |
---|---|
数据库 database | 索引 index |
表 table | types |
行 rows | documents |
字段 columns | fields |
物理设计
es在后台将每个索引划分成多个分片,每个分片可以在集群中的不同服务器间迁移。
一个人就是一个集群!
逻辑设计
Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。
index索引
索引是映射类型的容器,它存储了映射类型的字段和其他设置。一个索引就是一个拥有几分相似特征的文档的集合。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。
type类型
类型是文档的逻辑容器,就像关系型数据库一样,表是行的容器。在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。
Filed字段
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识 。
映射mapping
对字段的定义称为映射,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。相当于mysql中的创建表的过程,设置主键外键等等。
document文档
一个文档是一个可被索引的基础信息单元。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。 插入索引库以文档为单位,类比与数据库中的一行数据。
尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段可以是字符串类型,也可以是整型。
集群cluster
一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由 一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集 群的名字,来加入这个集群,这种类型有时候称为映射类型。在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点, 这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。
节点和分片 如何工作
一个集群至少有一个节点,而一个节点就是一个es的进程,节点可以有多个索引,如果你创建索引,那么索引就会有5个分片(其中primary shard 称为主分片)构成,每一个主分片都有一个副本(replica shard 称为复制分片)。
上图是一个有3个节点的集群,有8个分片(其中P1是索引1的主分片,R1是其复制分片),我们可以看到,同一索引的主分片和复制分片都不在同一节点下,这样的好处是当一个节点挂了,改索引还能用,数据不至于丢失。一个分片是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引能加快搜索,是的es在不扫描全部文档的情况下,能告诉你哪些文档有哪些关键字。
倒排索引
倒排索引以lucene为底层,用于快速全文检索,一个索引由文档中所有不重复的列表构成,对于每一个词都有一个包含它的文档列表。
文档1 It like apple,I am a boy
文档2 Apple like it , Am i a boy
为了创建倒排索引,先拆分成不同的词,创建包含所有不重复的词条的排序列表,然后列出词出现在哪个文档。
term | doc_1 | doc_2 |
---|---|---|
It | ✔ | |
it | ✔ | |
like | ✔ | ✔ |
apple | ✔ | |
am | ✔ | |
I | ✔ | |
a | ✔ | ✔ |
boy | ✔ | ✔ |
Apple | ✔ | |
Am | ✔ |
两个文档都匹配,但文档一匹配度更高。
来看下一个例子:
原始的查询,比如查询标签是java的文章,会从根据id查询所有数据,而对于倒排索引而言,只需要搜索标签是否为java,就可以返回所有需要的文章id。就此可以看出,倒排索引可以提高搜索的速度。
IK分词器
es默认是不支持中文分词的,他只会讲一句中文话拆分成一个个汉字。而我们需要的是想英文一样拆分成一个个单词,就需要安装ik分词器。
ik_smart和ik_max_word
ik分词器提供两种算法ik_smart和ik_max_word,其中ik_smart是最少切分,ik_max_word是最细粒度划分。
在kibana中输入
GET _analyze
{
"analyzer": "ik_smart",
"text": "我爱中国"
}
结果是
GET _analyze
{
"analyzer": "ik_max_word",
"text": "中国共产党"
}
结果是
安装
- 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
- 解压,将解压后的elasticsearch文件夹拷贝到elasticsearch-7.6.1\plugins下,并重命名文件夹为analysis-ik
(其他名字也可以,目的是不要重名) - 重新启动ElasticSearch,即可加载IK分词器
分词器添加自己配置
有时候我们要搜索”的得到“这个词,但这个词是我们编造的,ik分词器是不识别的,不会分作一个词,而是分成三个字,怎么办呢?
进入到下面文件夹\elasticsearch-analysis-ik-7.6.1\config
你会发现这里存的就是一下分词词典,这时你学着创建一个:
再在IKAnalyzer.cfg.xml中配置
这就可以搜索到了。
Rest风格操作
Rest风格是es的特色之一。
REST是一种软件架构风格,或者说是一种规范,其强调HTTP应当以资源为中心,并且规范了URI的风格;规范了HTTP请求动作(GET/PUT/POST/DELETE/HEAD/OPTIONS)的使用,具有对应的语义。
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 | 查询所有数据 |
基本操作
以下使用kibana,左侧导航栏点击这个图标到查询页面。
创建索引
直接创建索引
PUT /test2
也可以同时插入数据
PUT /test/type1/1
{
"name":"sss",
"age":3
}
创建index并添加映射mapping
PUT /test/type1/1
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index": "not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index": "analyzed",
"analyzer": "standard"
},
"content": {
"type": "text",
"store": true,
"index": "analyzed",
"analyzer": "standard"
}
}
}
}
}
删除索引
DELETE test
创建文档document
POST /test/article/1
修改document
POST /test/article/1
{
"text": ww"
"text2": "中国共产党"
}
这个不推荐,因为如果在请求提漏了一个属性,修改document时就会少一个属性
POST /test/type1/1/_update
{
"test":"sss"
}
删除文档document
DELETE /test/article/1
查询更多信息
通过 _cat可以看到更多配置,存储信息。
GET _cat
复杂操作
结果过滤
GET test/_doc/_search
{
"query":{
"match":{
"name":"中国"
}
},
"_source":["name","desc"]
}
排序
GET test/_doc/_search
{
"query":{
"match":{
"name":"中国"
}
},
"sort":{
"age":{
"order":"desc"
}
}
}
分页
GET test/_doc/_search
{
"query":{
"match":{
"name":"中国"
}
},
"from":0,
"size":2
}
布尔值查询,多条件查询
GET test/_doc/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"中国"
}
},
{
"match":{
"age":"23"
}
}
]
}
}
}
must相当于and,should相当于or,must_not相当于not
filter过滤
GET test/_doc/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"中国"
}
}
]
,
"filter":{
"range":{
"age":{
"gte":1,
"lte":35
}
}
}
}
}
}
gt 大于
gte 大于等于
lt 小于
lte 小于等于
匹配多个条件
GET test/_doc/_search
{
"query":{
"match":{
"tag":"中国 男"
}
}
}
匹配多个条件,多个条件空格隔开,满足其一即可
精确查询
term 和match
- term ,直接精确查询
- match,会使用分词,再查询
text和keyword - text,会被分词
- keyword,其值为一个词,不会被分词
高亮
GET test/_doc/_search
{
"query":{
"match":{
"name":"中国"
}
},
"highlight":{
"pre_tags":"<p style='color:red'>",
"post_tags":"</p>",
"fields":{
"name":{}
}
}
}
总结
ElasticSearch是一个很好的搜索引擎,只要你做关于搜索的功能都可以用到他,本文是是笔者的es学习笔记,篇幅原因,与springboot的整合就留到下篇文章。文中有什么不对的地方可以提出交流。
与springboot整合
https://blog.csdn.net/hehe_cxh/article/details/109461997