Elasticsearch 保姆级教程(文末送书)

Elasticsearch 介绍

1. Elasticsearch

Elasticsearch 是一个基于 Apache Lucene 的开源搜索引擎。无论在开源还是专有领域,Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。

特点:

Elasticsearch 也使用 Java 开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单。

ES 能做什么?

全文检索(全部字段)、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)

2. Elasticsearch 使用案例

2013 年初,GitHub 抛弃了 Solr,采取 Elasticsearch 来做 PB 级的搜索。“GitHub 使用 Elasticsearch 搜索 20TB 的数据,包括 13 亿文件和 1300 亿行代码”

维基百科:启动以 Elasticsearch 为基础的核心搜索架构

百度:百度目前广泛使用 Elasticsearch 作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部 20 多个业务线(包括 casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大 100 台机

新浪使用 ES 分析处理 32 亿条实时日志

阿里使用 ES 构建挖财自己的日志采集和分析体系

3. Elasticsearch 对比 Solr

Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能

Solr 支持更多格式的数据,而 Elasticsearch 仅支持 json 文件格式

Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供

Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch

4. Elasticsearch 基本概念及架构

1) Elasticsearch 基本概念
1. 索引 index
2. 映射 mapping
3. 字段 Field

相当于是数据表的字段,对文档数据根据不同属性进行的分类标识

4. 类型 Type

每一个字段都应该有一个对应的类型,例如:Text、Keyword、Byte 等

5. 文档 document
6. 集群 cluster
7. 节点 node
8. 分片和副本 shards&replicas

分片:

副本:

2) Elasticsearch 基本架构

docx image

Gateway 是 ES 用来存储索引的文件系统,支持多种类型。

Gateway 的上层是一个分布式的 lucene 框架。

Lucene 之上是 ES 的模块,包括:索引模块、搜索模块、映射解析模块等。

ES 模块之上是 Discovery、Scripting 和第三方插件。

Discovery 是 ES 的节点发现模块,不同机器上的 ES 节点要组成集群需要进行消息通信,集群内部需要选举 master 节点,这些工作都是由 Discovery 模块完成。支持多种发现机制,如 Zen 、EC2、gce、Azure。

Scripting 用来支持在查询语句中插入 javascript、python 等脚本语言,scripting 模块负责解析这些脚本,使用脚本语句性能稍低。ES 也支持多种第三方插件。

再上层是 ES 的传输模块和 JMX.传输模块支持多种传输协议,如 Thrift、memecached、http,默认使用 http。JMX 是 java 的管理框架,用来管理 ES 应用。

最上层是 ES 提供给用户的接口,可以通过 RESTful 接口和 ES 集群进行交互。

Elasticsearch 基础使用

对 Elasticsearch 操作有多种工具,这里我们使用 Kibana,先简单介绍下。

1. Kibana 的基本介绍

Kibana 是一个开源的分析和可视化平台,设计用于和 Elasticsearch 一起工作。

可以用 Kibana 来搜索,查看,并和存储在 Elasticsearch 索引中的数据进行交互

可视化数据

Kibana 使得理解大量数据变得很容易。它简单的、基于浏览器的界面使你能够快速创建和共享动态仪表板,实时显示 Elasticsearch 查询的变化。

2. ES 操作前须知

1) REST 和 CURL 介绍:
REST:

REST 约定用 HTTP 的请求头 POST、GET、PUT、DELETE 正好可以对应 CRUD(Create、Read、Update、Delete)四种数据操作。

如下表所示:

CURL:

curl 是利用 URL 语法在命令行方式下工作的开源文件传输工具,使用 curl 可以简单实现常见的 get/post 请求。简单的认为是可以在命令行下面访问 url 的一个工具。在 centos 的默认库里面是有 curl 工具的,如果没有请 yum 安装即可。

curl 后面可跟参数:

-X 指定 http 的请求方法 有HEAD GET POST PUT DELETE

-d 指定要传输的数据

-H 指定 http 请求头信息

Elasticsearch 提供了非常全面和强大的 REST API,通过这些 API,我们可以了解集群的信息。这些 API 可以做如下事情:

检查集群、节点和索引的情况、状态和统计。

管理集群、节点、索引数据和文档数据。

执行 CRUD(创建、读取、更新和删除)操作,可以对索引进行操作。

执行高级搜索操作,如分页、排序、过滤、脚本、聚合及其他操作。

2) ES 请求方式

首先说下请求 ES 的方式,后面例子都是这种方式:

请求参数:curl -X{PUT} http://{host}:{port}

例如:curl -XPUT http://120.0.0.1:9200/blog1?pretty

在 Kibana 中可直接输入 PUT /blog1?pretty

body 参数:{参数内容}

注意:

请求方法 GET 和 DELETE 上面介绍了,比较简单,不过多说,主要说下 POST 和 PUT 在 ES 中的使用:

POST 和 PUT 共同点:

POST 和 PUT 不同点:

3. ES API 操作

1) 创建索引

同一个索引中存储了相同类型的文档,它就相当于 MySQL 中的表,或相当于 Mongodb 中的集合

关于索引这个语:

索引(名词):ES 是基于 Lucene 构建的一个搜索服务,它要从索引库搜索符合条件索引数据。索引(动词):索引库刚创建起来是空的,将数据添加到索引库的过程称为索引。

PUT http://node01:9200/索引名称?pretty

上面命令最后有个 pretty,什么意思呢,在任意的查询字符串中增加 pretty 参数,会让 Elasticsearch 美化输出(pretty-print) JSON 响应以便更加容易阅读。

打开 kibana,找到 dev tools

docx image

出现如下页面,左边是执行区,右边是结果返回区:

docx image

左边框中执行以下语句:

上述语句直接粘贴到 kibana 的 dev tools,如下左边所示,它会自动帮我们格式化语句,像 curl -X,和地址都自动隐藏了。

docx image

上面执行的命令并没有设置 body 参数,执行的就是默认参数。

执行如下带 body 参数的语句:

number_of_shards

number_of_replicas

docx image

创建索引相当于关系数据库中的数据库还是表?

2) 插入文档

ES 中的文档相当于 MySQL 数据库表中的数据

使用 PUT 将一个文档添加到 /_doc(文档类型),并为该文档分配 ID 为 1。URL 路径显示为 index/doctype/ID(索引/文档类型/ID)。

注意

上面说的文档类型,也叫映射类型(type)

什么是映射类型?

映射类型 简单理解相当于关系数据库的表(不准确,后面会说),每个索引里都可以有一个或多个映射类型,映射类型是 index 中的一个逻辑数据分类,一个映射类型下的文档(document),都有相同的字段(field)。

ES 6.0 之前的版本有映射类型(type) 概念,但是官方将在 ES9.0 版本中彻底删除映射类型。

为什么要移除映射类型?

开始的时候,我们说“索引(index)”类似于 SQL 数据库中的“数据库”,将“类型(type)”等同于“表”。

这是一个糟糕的类比,并且导致了一些错误的假设。在 SQL 数据库中,表之间是相互独立的。一个表中的各列并不会影响到其它表中的同名的列。而在映射类型(mappingtype)中却不是这样的。

在同一个 Elasticsearch 索引中,其中不同映射类型中的同名字段在内部是由同一个 Lucene 字段来支持的。换句话说,假如有两个映射类型 user 和 tweet,user 类型中的 user_name 字段与 tweet 类型中的 user_name 字段是完全一样的,并且两个 user_name 字段在两个类型中必须具有相同的映射(定义)。

这会在某些情况下导致一些混乱,比如,在同一个索引中,当你想在其中的一个类型中将 deleted 字段作为 date 类型,而在另一个类型中将其作为 boolean 字段。

在此之上需要考虑一点,如果同一个索引中存储的各个实体如果只有很少或者根本没有同样的字段,这种情况会导致稀疏数据,并且会影响到 Lucene 的高效压缩数据的能力。

基于这些原因,将映射类型的概念从 Elasticsearch 中移除。

所以

在 ES6.0 及之后版本中要弱化映射类型的概念,尽量设置一个无任何业务含义的名字,本文档的所有映射类型都统一设为_doc。

3) 查询文档

docx image

4) 更新文档

docx image

5) 搜索文档

docx image

返回值说明

1. Hits

返回结果中最重要的部分是  hits ,它包含  total  字段来表示匹配到的文档总数,并且一个  hits  数组包含所查询结果的前十个文档。

在  hits  数组中每个结果包含文档的  _index 、 _type 、 _id ,加上  _source  字段。这意味着我们可以直接从返回的搜索结果中使用整个文档。这不像其他的搜索引擎,仅仅返回文档的 ID,需要你单独去获取文档。

每个结果还有一个  _score ,它衡量了文档与查询的匹配程度。默认情况下,首先返回最相关的文档结果,就是说,返回的文档是按照  _score  降序排列的。

max_score  值是与查询所匹配文档的  _score  的最大值。

2. took

took  值告诉我们执行整个搜索请求耗费了多少毫秒。

3. Shard

_shards  部分告诉我们在查询中参与分片的总数,以及这些分片成功了多少个失败了多少个。正常情况下我们不希望分片失败,但是分片失败是可能发生的。

如果我们遭遇到一种灾难级别的故障,在这个故障中丢失了相同分片的原始数据和副本,那么对这个分片将没有可用副本来对搜索请求作出响应。假若这样,Elasticsearch 将报告这个分片是失败的,但是会继续返回剩余分片的结果。

4. timeout

timed_out  值告诉我们查询是否超时。默认情况下,搜索请求不会超时。  如果低响应时间比完成结果更重要,你可以指定  timeout  为 10 或者 10ms(10 毫秒),或者 1s(1 秒):

GET /_search?timeout=10ms

在请求超时之前,Elasticsearch 将会返回已经成功从每个分片获取的结果。

6) 删除文档
7) 删除索引
8) 创建映射

概念说明

创建映射就是向索引库中创建字段及字段类型等的过程

文档(Document)——Row 记录字段(Field)——Columns 列

为什么要映射?

ES 中的文档等价于 java 中的对象,那么在 java 对象中有字段类型(比如 string、int、long 等),同理在 ES 索引中的具体字段也是有类型的。

像下面这个操作:

这种操作并没有指定字段类型,那么 Elasticsearch 会自动根据数据类型的格式识别字段的类型;

查看索引的字段类型:

GET /document/_mapping

可以发现 titleScore 的类型是 long。

docx image

然后在插入一条数据,注意此时 titleScore 的值不是 long 类型:

查询数据:

GET /document/_doc/2

我们会发现 ES 能存入,并没有报错(注意),这其实是一个问题

对于 titleScore,设置什么类型合适?使用 long 类型,那么后面肯定会有数据格式转换的异常 double-long

所以,我们如果能提前知道字段类型,那么最好使用 mapping 的映射管理,提前指定字段的类型,防止后续的程序问题

先删除之前创建的索引:DELETE document

创建映射命令

创建索引,并指定映射:

查看索引:GET document/_mapping

docx image

对这个索引继续添加字段

查看索引:GET document/_mapping

docx image

9) 映射字段的类型

在 Elasticsearch 中,每一个字段都有一个类型(type)。以下为 Elasticsearch 中可以使用的类型:

10) 获取映射字段

语法:GET /{index}/_mapping/field/{field}

docx image

11) 索引库配置管理(settings)

所谓的 settings 就是用来修改索引分片和副本数的。

比如有的重要索引,副本数很少甚至没有副本,那么我们可以通过 setting 来添加副本数。

查看 settings:GET /document/_settings

docx image

可以看到当前的副本数是 1,那么为了提高容错性,我们可以把副本数改成 2:

docx image

注意:副本可以改,分片不能改!

执行如下语句会报错:

4. ES 花式查询

我们先插入一些数据,后面查询时以这些数据为例。

在 Kibana 界面上执行如下语句,插入一些数据:

1) 使用 match_all 做查询

问题

2) 通过关键字段进行查询

喜欢旅游的,并且不能是男孩的

这样写是否可以:

docx image

因为一个 match 下,不能出现多个字段值,需要使用复合查询。

3) bool 的复合查询

当出现多个查询语句组合的时候,可以用 bool 来包含。

bool 合并聚包含:must,must_not 或者 should, should 表示 or 的意思。

例:查询非男性中喜欢旅行的人

4) bool 的复合查询中的 should

should 表示可有可无的(如果 should 匹配到了就展示,否则就不展示)

例:查询喜欢旅行的,如果有男性的则显示,否则不显示

5) term 匹配

使用 term 进行精确匹配(比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型))

语法:

{ “term”: { “age”: 20 }}{ “term”: { “date”: “2018-04-01” }}{ “term”: { “sex”: “boy” }}{ “term”: { “about”: “trivel” }}

例:

6) 使用 terms 匹配多个值

注意:term 和 match 区别:

term 主要是用于精确的过滤比如说:”我爱你”

在 match 下面匹配可以为包含:我、爱、你、我爱等等的解析器

在 term 语法下面就精准匹配到:”我爱你”

7) Range 过滤

Range 过滤允许我们按照指定的范围查找一些数据:操作范围:gt: 大于,gae: 大于等于,lt: 小于,lte: 小于等于

例:查找出大于 20 岁,小于等于 25 岁的学生

8) exists 和 missing 过滤

exists 和 missing 过滤可以找到文档中是否包含某个字段或者是没有某个字段。

例:查找字段中包含 age 的文档

9) bool 的多条件过滤

用 bool 也可以像之前 match 一样来过滤多行条件:

must : 多个查询条件的完全匹配,相当于 and 。must_not : 多个查询条件的相反匹配,相当于 not 。should : 至少有一个查询条件匹配, 相当于 or 。

例:过滤出 about 字段包含 travel 并且年龄大于 20 岁小于 30 岁的同学

10) 查询与过滤条件合并

通常复杂的查询语句,我们也要配合过滤语句来实现缓存,用 filter 语句就可以来实现。

例:查询出喜欢旅行的,并且年龄是 20 岁的文档

5. 零停机重新索引数据

实际生产,对于文档的操作,偶尔会遇到这种问题:

某一个字段的类型不符合后期的业务了,但是当前的索引已经创建了,我们知道 ES 在字段的 mapping 建立后就不可再次修改 mapping 的值。

1) 新建索引库 articles1
2) 索引库 articles1 添加数据
3) 新建索引库 articles2
4) 拷贝数据并验证

验证数据:

docx image

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容