ElasticSearch入门到精通
ElasticSearch概述
Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单。
据国际权威的数据库产品评测机构 DB Engines 的统计,在2016年1月,ElasticSearch已超过Solr等,成为排名第一的搜索引擎类应用。
为了增加学习的趣味性,我们来聊一聊 elasticsearch 的历史
历史
多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。在他找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。
直接基于Lucene工作会比较困难,所以Shay开始抽象Lucene代码以便Java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做“Compass”。
后来Shay找到一份工作,这份工作处在高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是理所当然需要的。然后他决定重写Compass库使其成为一个独立的服务叫做Elasticsearch。
第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过 Elasticsearch 将永远开源且对所有人可用。
Shay的妻子依旧等待着她的食谱搜索……
ES 和 solr 的差别
学习 ES,我们免不了需要跟 solr 进行对比学习!下面我们分别来看看,它们之间具体的差别在哪里:
Elasticsearch 简介
Elasticsearch 是一个实时分布式搜索和分析引擎。它让你以前所未有的速度处理大数据成为可能。
它用于全文搜索、结构化搜索、分析以及将这三者混合使用:
维基百科使用Elasticsearch提供全文搜索并高亮关键字,以及输入 实时搜索(search-asyou-type)和 搜索纠错(did-you-mean)等搜索建议功能。
英国卫报使用Elasticsearch结合用户日志和社交网络数据提供给他们的编辑以实时的反馈,以便及时了解公众对新发表的文章的回应。
StackOverflow结合全文搜索与地理位置查询,以及more-like-this功能来找到相关的问题和答案。
Github使用Elasticsearch检索1300亿行的代码。
但是 Elasticsearch 不仅用于大型企业,它还让像DataDog 以及 Klout 这样的创业公司将最初的想法变成可扩展的解决方案。
Elasticsearch可以在你的笔记本上运行,也可以在数以百计的服务器上处理PB级别的数据 。
Elasticsearch 是一个基于 Apache Lucene(TM) 的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库
但是,Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的
Elasticsearch也使用Java开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单
Solr 简介
Solr 是 Apache 下的一个顶级开源项目,采用Java开发,它是基于 Lucene 的全文搜索服务器。Solr提供了比 Lucene 更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Solr可以独立运行,运行在Jetty、Tomcat 等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据 xml 文档添加、删除、更新索引。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运 行情况。
Solr是基于 lucene 开发企业级搜索服务器,实际上就是封装了lucene。
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的文件,生成索引;也可以通过提出查找请求,并得到返回结果。
Lucene简介
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。
Lucene是一个全文检索引擎的架构。那什么是全文搜索引擎?
全文搜索引擎是名副其实的搜索引擎,国外具代表性的有Google、Fast/AllTheWeb、AltaVista、Inktomi、Teoma、WiseNut等,国内著名的有百度(Baidu)。它们都是通过从互联网上提取的各个网站的信息(以网页文字为主)而建立的数据库中,检索与用户查询条件匹配的相关记录,然后按一定的排列顺序将结果返回给用户,因此他们是真正的搜索引擎。
从搜索结果来源的角度,全文搜索引擎又可细分为两种,一种是拥有自己的检索程序(Indexer),俗称“蜘蛛”(Spider)程序或“机器人”(Robot)程序,并自建网页数据库,搜索结果直接从自身的数据库中调用,如上面提到的7家引擎;另一种则是租用其他引擎的数据库,并按自定的格式排列搜索结果,如 Lycos 引擎。
Elasticsearch和Solr比较
ElasticSearch vs Solr 总结
1、es基本是开箱即用,非常简单。Solr安装略微复杂一丢丢!
2、Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能。
3、Solr 支持更多格式的数据,比如JSON、XML、CSV,而 Elasticsearch 仅支持json文件格式
4、Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑
5、Solr 查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用;
- ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。
- Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。
6、Solr 比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而 Elasticsearch 相对开发维护者较少,更新太快,学习使用成本较高。
所以如果我们在做技术选型的时候,具体选择哪一项技术,还需要根据不同的场景来进行结合选择。
哈哈哈,好像跑题了,下面我们就正式进入到 elasticsearch 的学习中!
安装elasticsearch
我们首先来到 es 的官网,根据自己不同的操作系统,点击即可下载最新版本的产品,目前最新版本是Elasticsearch 7.11
上传安装包到linux并解压
我的习惯是将所有的软件包放到/export/software目录下,解压后的目录是/export/servers
1 | [root@node01 software]# tar -zxvf elasticsearch-7.11.0-linux-x86_64.tar.gz -C ../servers/ |
目录结构
解压完毕之后,我们先来熟悉es的目录结构
1 | [root@node01 elasticsearch-7.11.0]# ll /export/servers/elasticsearch-7.11.0 |
其中我们常用的目录有:
- bin:可执行文件在里面,运行es的命令就在这个里面,包含了一些脚本文件等
- config:配置文件目录
- JDK:java环境
- lib:依赖的jar,类库
- logs:日志文件
- modules:es相关的模块
- plugins:可以自己开发的插件
- data:这个目录没有,自己新建一下,后面要用 -> mkdir data,这个作为索引目录
修改配置文件
熟悉完es的目录,在启动es前,我们还需要修改一些配置文件
核心配置文件 elasticearch.yml
1 | [root@node01 elasticsearch-7.11.0]# vim config/elasticsearch.yml |
- 修改集群名称
- 修改当前的 es 节点名称
- 修改data数据保存地址和日志数据保存地址
- 绑定 es 网络 ip
- 集群节点修改为之前的节点名称
具体位置如下图所示:
修改 jvm 参数
因为 Elasticsearch 是用 Java 语言开发的,所以我们在配置环节一定少不了修改 jvm 的参数
1 | [root@node01 elasticsearch-7.11.0]# vim config/jvm.options |
根据自己当前操作系统的不同配置,设置不同的大小即可
添加用户
比较有意思的一点是,es不允许使用 root 来操作 es,需要我们添加用户,具体的命令如下:
1 | # 1. 创建elsearch用户组及elsearch用户: |
启动es
修改完上面2个配置文件,我们切换到bin目录下,通过./elasticsearch启动es
不出意外,应该会报如下错误:
1 | ERROR: [3] bootstrap checks failed |
我们只需要将最大的线程数设置大一些即可
我们切换回到root目录
- 修改
/etc/security/limits.conf文件
添加以下内容
1 | * soft nofile 65536 |
如下图所示:
- 修改 /etc/sysctl.conf 增加
vm.max_map_count=262145
记得将防火墙关闭或者将9200端口打开,否则就会出现启动成功,页面无法访问的情况
启动与暂停
启动与暂停这里也分成2种形式
启动方式1
我们在bin目录下直接./elasticsearch,可以看到运行结果
然后根据自己的 ip:9200进行访问,可以在界面上看到如下返回的结果
当前启动方式是前端启动。停止服务的话直接ctrl+c 就好了
启动方式2
同时,我们也可以后端启动
1 | [esuser@node01 bin]$ ./elasticsearch -d |
稍等片刻,再次访问地址,还是相同结果
此时,如果想关闭服务
1 | [esuser@node01 bin]$ ps -ef|grep elasticsearch |
然后将对应的进程id kill掉即可!
接下来我们需要安装ES的图形化界面插件,也就是elasticsearch-head,这里介绍2种方法,方法1比较麻烦,想省事的同学可以直接划到下方的方法2,利用谷歌插件进行安装,简单高效!
安装elasticsearch-head(方法1)
elasticsearch-head是一款开源软件,被托管在github上面,所以如果我们要使用它,必须先安装git,通过git获取elasticsearch-head
给大家看下这个项目,已经斩获 7.3K 的start,说明还是非常受大众欢迎
需要注意的是, 运行elasticsearch-head会用到 grunt,而 grunt 需要 npm 包管理器,所以 nodejs 是必须要安装的
安装npm
当然如果你的环境里已经安装好了npm,那则可以跳过这一步。
(1) 安装gcc
1 | yum install gcc gcc-c++ |
(2) 下载node国内镜像(推荐)
1 | wget https://npm.taobao.org/mirrors/node/v10.14.1/node-v10.14.1-linux-x64.tar.gz |
(3) 解压并重命名文件夹
解压
1 | tar -xvf node-v10.14.1-linux-x64.tar.gz |
然后重命名文件夹
1 | mv node-v10.14.1-linux-x64 node |
(4) 添加环境变量
1 | vi /etc/profile |
在文件最后添加以下配置:
1 | export NODE_HOME=/export/servers/node |
(5) 刷新配置
1 | source /etc/profile |
(6) 验证结果
1 | node -v |
能够正确显示版本号即说明 nodejs 环境安装成功
安装cnpm
我们上面谈到的 npm 命令是 node.js 的 npm 插件管理器,也就是下载插件安装插件的管理器。但我们在使用的时候,下载的都是国外服务器很慢会掉线,所以这一步,我们需要安装淘宝的 npm 镜像cnpm。
也非常简单,执行如下命令即可
1 | npm install -g cnpm --registry=https://registry.npm.taobao.org |
排雷:如果遇到
this is a problem related to network connectivity, behind a proxy的异常,执行npm config set proxy null将代理设置为空即可再重试上面的命令即可。
cnpm 正常安装完成之后呢,效果图如下:
下载依赖
现在环境都准备好了,那我们该做些什么呢?其实 GitHub 上都已经写明白了
我们进入到elasticsearch-head的目录下,执行命令,下载相关的依赖
1 | [root@node01 elasticsearch-head]# cnpm install |
1 | [root@node01 elasticsearch-head]# npm run start |
然后我们就可以在浏览器上通过 ip:9100 访问到如下页面,但是当我们点击连接,在控制台又会出现 Error 信息,这是为什么呢?
1 | [root@node01 elasticsearch-7.11.0]# vim config/elasticsearch.yml |
配置完毕,我们重启ES,重新连接,就能正常看到正常的页面了
安装elasticsearch-head(方法2)
不知道大家有没有对于操作到这一步,在想着有没有更简单的方式安装 elasticsearch-head 呢?
当然有,我们在 readme 文件中,发现也可以通过在谷歌浏览器上使用插件的形式来进行安装 elasticsearch-head
如果是初学的小伙伴,就算成功看到这个页面可能还有点懵,因为现在这个网站上还没有什么东西
我们初学,就把 es 当做一个数据库,可以建立索引(库),文档(库中的数据!)
现在还没有索引,我这里就先创建了一个alice索引
安装Kibana
了解ELK
ELK是
Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为 ElasticStack 。其中 Elasticsearch 是一个基于 Lucene、分布式、通过 Restful 方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用 Elasticsearch 作为底层支持框架,可见 Elasticsearch 提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是 ELK 的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将 elasticsearch 的数据通过友好的页面展示出来,提供实时分析的功能。
看了上面的描述,我们大概心里就已经清楚,ELK 的流程大致就是 收集清理数据 -> 搜索,存储 -> Kibana,如下所示:
市面上很多开发只要提到 ELK 能够一致说出它是一个日志分析架构技术栈 总称,但实际上 ELK 不仅仅适用于日志分析,它还可以支持其它任何数据分析和收集的场景,日志分析和收集只是更具有代表性,并非唯一性。
Kibana的安装
Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在 Elasticsearch 索引中的数据。使用 Kibana ,可以通过各种图表进行高级数据分析及展示。Kibana 让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch 查询动态。设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成 Kibana 安装并启动 Elasticsearch 索引监测。
官网地址:https://www.elastic.co/cn/kibana
1 | [root@node01 software]# tar -zxvf kibana-7.11.0-linux-x86_64.tar.gz -C ../servers/ |
修改conf目录下的kibana.yml文件,添加上如下的几行配置
1 | i18n.locale: "zh-CN" |
然后重新启动 kibana ,即可看到效果
踩坑
kibana 启动,可能会遇到这个 bug:
1 | Error: Unable to write Kibana UUID file, please check the uuid.server configuration value in kibana.yml and ensure Kibana has sufficient permissions to read / write to this file. Error was: EACCES |
解决方案 就是:
1 | # 在root下为 为kibana赋权 |
ES的核心概念
概述
在前面的学习中,我们已经掌握了 es 是什么,同时也把 es 的服务已经安装启动,那么 es 是如何去存储数据,数据结构是什么,又是如何实现搜索的呢?我们先来聊聊 ElasticSearch的相关概念 吧
集群,节点,索引,类型,文档,分片,映射是什么?
对比
ElasticSearch 是面向文档的非关系型数据库,下面让我们来看看它与关系型数据库的客观对比!
| Relational DB | Elasticsearch |
|---|---|
| 数据库(database) | 索引(indices) |
| 表(tables) | types |
| 行(rows) | documents |
| 字段(columns) | fields |
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)
物理设计:
elasticsearch 在后台把每个索引划分成多个分片,每份分片可以在集群中的不同服务器间迁移
逻辑设计:
一个索引类型中,包含多个文档,比如说文档1,文档2。 当我们索引一篇文档时,可以通过这样的一个顺序找到 它: 索引 ▷ 类型 ▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。 注意 : ID不必是整数,实际上它是个字符串。
文档
之前说 elasticsearch 是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch 中,文档有几个 重要属性 :
- 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 key:value!
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的!其实就是个JSON对象
- 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在 elasticsearch 中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。
尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整形。因为 elasticsearch 会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型,这也是为什么在 elasticsearch 中,类型有时候也称为映射类型。
类型
类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。 类型中对于字段的定义称为映射,比如 name 映 射为字符串类型。 我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,那么 elasticsearch 是怎么做的呢?elasticsearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型,elasticsearch就开始猜,如果这个值是18,那么elasticsearch会认为它是整形。 但是elasticsearch也可能猜不对, 所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库殊途同归了,先定义好字段,然后再使用。
索引
索引是映射类型的容器,elasticsearch 中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。 然后它们被存储到了各个分片上了。 我们来研究下分片是如何工作的。
物理设计 :节点和分片如何工作
一个集群至少有一个节点,而一个节点就是一个 elasricsearch 进程,节点可以有多个索引默认的,如果你创建索引,那么索引将会有个5个分片 ( primary shard ,又称主分片 ) 构成的,每一个主分片会有一个副本 ( replica shard ,又称复制分片 )
倒排索引
elasticsearch 使用的是一种称为倒排索引的结构,采用Lucene倒排索引作为底层。这种结构适用于快速的全文搜索, 一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。 例如,现在有两个文档, 每个文档包含如下内容:
1 | Study every day, good good up to forever # 文档1包含的内容 |
为了创建倒排索引,我们首先要将每个文档拆分成独立的词(或称为词条或者tokens),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档 :
再来看一个示例,比如我们通过博客标签来搜索博客文章。那么倒排索引列表就是这样的一个结构 :
在 elasticsearch 中, 索引这个词被频繁使用,这就是术语的使用。在 elasticsearch 中,索引被分为多个分片,每份分片是一个 Lucene 的索引。所以 一个 elasticsearch 索引是由多个Lucene索引组成的。别问为什么,谁让elasticsearch使用Lucene作为底层呢! 如无特指,说起索引都是指elasticsearch的索引。
ES基础操作
IK 分词器
什么是IK分词器?
分词:即把一段中文或者别的内容划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,是因为数据库中或者索引库中的数据也会进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,比如 “我爱大数据” 会被分为”我”,”爱”,”大”, “数”,”据”,这显然是不符合要求的,所以我们需要安装中文分词器 ik 来解决这个问题。
提前说一嘴,IK提供了两个分词算法:ik_smart 和 ik_max_word ,其中 ik_smart 为最少切分,ik_max_word 为 最细粒度划分!这个我们后面会来进行测试。
安装步骤
1、下载ik分词器的包,Github地址:https://github.com/medcl/elasticsearch-analysis-ik/ (版本要对 应)。但目前我们es的版本是7.11,而现在发布的最新 ik 分词器的版本也才 7.10.2,那我们就先下载最新的版本
1 | [root@node01 software]# wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.2/elasticsearch-analysis-ik-7.10.2.zip |
3. 解压下载好的压缩包,注意,解压路径必须放在 es 的 plugins 目录下
1 | [root@node01 software]# unzip elasticsearch-analysis-ik-7.10.2.zip -d ../servers/elasticsearch-7.11.0/plugins/ik |
4. 给文件夹权限
1 | [root@node01 plugins]# chmod 777 ik |
5. 正常情况下我们重启 Elasticsearch 即可看到插件加载的日志,但是很遗憾,终究因为版本不同的问题,导致 es 无法重启成功
然后我们打开 6.5.4 版本的 kibana 界面,可以发现跟我们最新下载的7.11 版本的 kibana 界面还是区别还是挺大的!
1 | GET _analyze |
返回的结果如下:
1 | GET _analyze |
此时返回的结果:
ik_max_word是细粒度分词,会穷尽一个语句中所有分词可能ik_smart是粗粒度分词,优先匹配最长词,不会有重复的数据
那大家有没有想过细粒度分词穷尽词库的可能,那词库是哪里的?一定是存在有类似”字典”这样的东西,不相信的话, 我们再用细粒度分词ik_max_word来做个测试
1 | GET _analyze |
此时返回的结果:
可以发现此时狂神说几个字被拆开了,那如果我们想让系统识别“狂神说”是一个词,就需要我们编辑自定义词库。
步骤同样非常简单: (1) 进入elasticsearch/plugins/ik/config目录
(2) 新建一个my.dic文件,编辑内容:
1 | 狂神说 |
(3) 修改IKAnalyzer.cfg.xml(在 ik/config 目录下)
1 | <properties> |
修改完配置重新启动 elasticsearch,再次测试!
到了这里,我们就明白了分词器的基本规则和使用了!实际上搜索引擎做的最重要的一件事,就是分词!它需要将我们搜索的内容进行关键字的拆分,然后展示对应的信息。那这些被拆分出来的词是如何划分权重的呢?不用担心,马上我们就来开始学习 es 基本的增删改查!
Rest风格说明
什么是 Rest 风格呢?
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
其中 基本 的 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 | 查询所有数据 |
那接下来我们就用之前已经安装好的 kibana 进行一个基础测试
关于索引的基本操作
基础测试
- 创建一个索引
PUT /索引名/类型名/文档id {请求id}
根据网址:ip:5601打开我们的 kibana 的页面,进入到开发工具栏,在 Console 中输入 :
1 | // 命令解释 |
如下图所示:
字段类型
elasticsearch 常见的字段类型如下:
- 字符串类型
- 数值类型
long, integer, short, byte, double, float, half_float, scaled_float
- 日期类型
date
- 布尔值类型
boolean
- 二进制类型
binary
- 等等
PUT新增
现在我们在kibana面板上新建一个索引并指定字段类型
1 | PUT /test2 |
输出如下,说明创建成功了
1 | { |
在elasticsearch-head上可以查看到我们目前还未添加任何数据
GET 查看
现在我们来尝试使用一下 GET 命令,请求具体的信息!
我们首先发起一个PUT请求,创建一个新的索引 test3,并添加一条数据
1 | PUT /test3/_doc/1 |
然后通过GET请求,可以发现非常的智能。但是如果我们的文档字段类型没有指定,那么es就会给我们默认配置的字段类型!
UPDATE修改
那如果我们想要修改文档里的字段信息呢?我们可以选择 UPDATE 也可以 选择 PUT进行覆盖
例如我可以像下图中的例子,将之前test3索引中的1号文档中的 name 字段修改后,重复提交,发现更新成功,但是注意 version 版本号已经变成了2
我们使用 POST 命令,在 id 后面跟 _update ,要修改的内容放到 doc 文档(属性)中即可。
DELETE删除
那么怎么删除一条索引呢(库)呢?我们需要使用到DELETE命令
其他命令
我们可以通过GET _cat/health来获取集群的一个健康状态
通过命令GET _cat/indices?v,我们可以获取到当前索引的很多信息,返回值包括所有索引的状态健康情况,分片,数据储存大小等等
关于文档的基本操作
接下来我们学习关于文档的基本操作,首先先重新创建一个新的索引,并添加一些数据
1 | PUT /alice/user/1 |
打开elasticsearch-head界面,确保我们的数据成功添加到了 es
简单查询
通过 GET 命令,我们可以搜索到指定 id 的文档信息
1 | GET alice/user/1 |
1 | 条件查询_search?q= |
我们可以通过如下命令,来进行条件查询
1 | GET alice/user/_search?q=name:张三 |
我们看一下结果 返回并不是 数据本身,是给我们了一个 hits ,还有 _score得分,就是根据算法算出和查询条件匹配度高的分就越高。
我们在以某度为例的搜索引擎上进行搜索也是一样的道理,权重越高网站的位置就越靠前!
但我们一般使用不会直接加条件去查询,更多的会用到下面要介绍到的复杂操作搜索。
复杂操作搜索 select( 排序,分页,高亮,模糊查询,精准查询!)
为了方便测试,我又执行下面的命令,往Alice索引下添加了2个文档
1 | PUT /alice/user/4 |
刷新,查看到现在已经有了5条数据:
1 | GET alice/user/_search |
1 | GET alice/user/_search |
如上例所示,在查询中,通过 _source 来控制仅返回 name 和 desc 属性。页面返回的查询结果如下:
排序查询
我们说到排序,有人就会想到:正序或倒序。那么我们先来根据age字段倒序查询:
1 | GET alice/user/_search |
查询返回的结果如下:
1 | GET alice/user/_search |
查询结果如下:
注意:在排序的过程中,只能使用可排序的属性进行排序。那么可以排序的属性有哪些呢?
- 数字
- 日期
- ID
其他都不行!
分页查询
学到这里,我们也可以看到,我们的查询条件越来越多,开始仅是简单查询,慢慢增加条件查询,增加排序,对返回结果进行限制。所以,我们可以说,对 于 elasticsearch 来说,所有的查询条件都是可插拔的。比如说,我们在查询中,仅对返回结果进行限制:
1 | GET alice/user/_search |
分页查询类似于我们SQL中的 limit 语句。在 es 中我们想要实现这样的效果只需要用 from 指定 从第几条数据开始,size指定返回多少条数据即可。
布尔查询
must (and)
我们上面已经讲过了通过构建查询的方法去做模糊查询,那我们如果想多条件查询,例如查询name为alice,并且age是25岁,那该如何查询呢?
我们通过在 bool 属性内使用 must 来作为查询条件!看结果,是不是 有点像and 的感觉,里面的条件需要都满足!
1 | GET alice/user/_search |
查询结果如下
那么我要查询name为爱丽丝或 age 为 25 的呢?
我们只需要将boolean属性内的must值换成should 即可,这就有点相当于 or 的感觉
1 | GET alice/user/_search |
查询结果如下
那现在我想要查询年龄不是 25 的 数据,只需要将boolean的属性值换成must_not即可
1 | GET alice/user/_search |
查询结果如下:
那如果查询 name 为爱丽丝,age 大于 24 的数据,需要使用到filter进行过滤。
1 | GET alice/user/_search |
查询结果如下,可以发现只有age为25 和 26的两条数据
- gt 表示大于
- gte 表示大于等于
- lt 表示小于
- lte 表示小于等于
那现在要查询,例如 age 在24到26之间的数据该如何查询?
1 | GET alice/user/_search |
查询结果:
短语检索
为了方便测试,我们再加入几条文档数据:
1 | PUT /alice/user/6 |
例如现在需要查询tags中包含“男”的数据
1 | GET alice/user/_search |
查询结果如下:
既然按照标签检索,那么,能不能写多个标签呢?
1 | GET alice/user/_search |
此时我们可以观察返回的结果,可以发现只要满足一个标签就能返回这个数据了
精确查询
term查询是直接通过倒排索引指定的词条进程精确查找的!
关于分词:
- term ,不经过分词,直接查询精确的值
- match,会使用分词器解析!(先分析文档,然后再通过分析的文档进行查询!)
说到分词器解析,就不得不提到两种数据类型:text和keyword。下面我们就来做个测试:
1 | // 创建一个索引,并指定类型 |
上述中testdb索引中,字段name在被查询时会被分析器进行分析后匹配查询。而属于keyword类型不会被分析器处理。
我们来验证一下:
1 | GET _analyze |
查询结果:
1 | GET _analyze |
查询结果:
下面我们用前面添加的2条数据做过测试:
先精准查询text类型的字段
1 | GET testdb/_search // text 会被分析器分析 查询 |
查询结果,2条数据都能匹配到
1 | GET testdb/_search // keyword 不会被分析所以直接查询 |
查询结果,只有1条数据能匹配到
查找多个精确值
为了方便测试,我们再添加如下数据:
1 | PUT testdb/_doc/3 |
然后进行查询
1 | GET testdb/_search |
查询结果:
当然,除了 bool 查询之外,下面这种方式也同样是可以的。
1 | GET testdb/_doc/_search |
下面要介绍的功能,就是经常被搜索引擎用到的“高亮显示”!
高亮显示
我们可以通过highlight属性,来对我们查询的结果的指定字段做高亮显示!
1 | GET alice/user/_search |
观察返回的结果,我们可以发现搜索相关的结果,被加上了高亮标签<em>
答案当然是可以的,我们需要在pre_tags中定义标签的前缀,post_tags中定义后缀!
1 | GET alice/user/_search |
查询结果:
- 简单匹配
- 条件匹配
- 精确匹配
- 区间范围匹配
- 匹配字段过滤
- 多条件查询
- 高亮查询
值得一提的是,这些MySQL也都能做,只是效率较低!

















































































