南国薏米

南国不须收薏苡,百年终竟是芭蕉。


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 公益 404

  • 搜索

Elastic Stack实战之Elasticsearch初体验(二)

发表于 2020-03-01 更新于 2020-07-18 分类于 hide 阅读次数:
本文字数: 6k 阅读时长 ≈ 5 分钟

【前面的话】前面我们已经安装好了Elasticsearch,现在我们就来尝试简单的使用。


壹、Elasticsearch介绍

2020010303

Elasticsearch是整个Elastic Stack的核心。

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。

通过 Elasticsearch,您能够执行及合并多种类型的搜索(结构化数据、非结构化数据、地理位置、指标),搜索方式随心而变。先从一个简单的问题出发,试试看能够从中发现些什么。找到与查询最匹配的 10 个文档是一回事。但如果面对的是十亿行日志,又该如何解读呢?Elasticsearch 聚合让您能够从大处着眼,探索数据的趋势和模式。

贰、插件安装

由于ES官方并没有为ES提供界面管理工具,仅仅是提供了后台的服务。elasticsearch-head是一个为ES开发的一个页面客户端工具,其源码托管于GitHub,地址为:
https://github.com/mobz/elasticsearch-head。
安装方法也比较多:

1.源码安装,通过npm run start启动
2.通过docker安装
3.通过chrome插件安装
4.通过ES的plugin方式安装

我这边就通过chrome插件的方式安装,在应用商店中搜索,然后安装即可,安装成功之后打开你会得到下面的页面

2020030106

然后连接集群,就可以进行操作了

2020030107

集群健康值
1.绿色:代表集群所有分片和副本都可用
2.黄色:代表集群中不是所有副本都可用,但是分片都可以用
3.红色: 代表集群中不是所有分片都可用

另外我的集群中出现了Unassigned,是因为我搭建的是单机版,而Elasticsearch默认会创建1个副本。

叁、简单使用

3.1 基本概念

索引

索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。

可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。

Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard),每个
分片可以有多个副本(replica)。

文档

存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库
表中的一行记录。

Elasticsearch和MongoDB中的文档类似,都可以有不同的结构,但Elasticsearch的文档中,相同字段必须有相
同类型。

文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。
每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数
组。

映射

所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做
映射(mapping)。一般由用户自己定义规则。

文档类型

在Elasticsearch中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章和评
论。

每个文档可以有不同的结构。

不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段
必须具有相同的类型。

3.2 RESTful API

在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。

下面我就通过Postman来演示一遍

3.2.1 创建非结构化索引

1
2
3
4
5
6
7
8
9
10
11
#创建索引
PUT /eelve

{
"settings": {
"index": {
"number_of_shards": "2", #分片数
"number_of_replicas": "0" #副本数
}
}
}

2020030108
2020030109

1
2
#删除索引
DELETE /eelve

2020030110

3.2.2 插入数据

URL规则:
POST /{索引}/{类型}/{id}

1、带id

1
2
3
4
5
6
7
8
POST /eelve/user/1001
#数据
{
"id":1001,
"name":"leo",
"age":26,
"sex":"男"
}

2020030111
2020030112

2、不带id

2020030113
2020030114

3.2.3 更新数据

在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新。

1、全部修改

2020030115
2020030116

2、部分修改

2020030117
2020030118

可以看到局部更新成功

3.2.4 删除数据

2020030120
2020030121

数据删除成功之后不会马上删除,只是会打上那个删除标识,Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。

3.2.5 搜索数据

1、根据id搜索

2020030123

2、全部搜索

2020030124

3、关键词搜索

2020030125

4、查询部分字段

2020030128

5、分页查询

和SQL使用 LIMIT 关键字返回只有一页的结果一样,Elasticsearch接受 from 和 size 参数:

size: 结果数,默认10
from: 跳过开始的结果数,默认0

2020030129

应该当心分页太深或者一次请求太多的结果。结果在返回前会被排序。但是记住一个搜索请求常常涉及多个分片。每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。

在集群系统中深度分页
为了理解为什么深度分页是有问题的,让我们假设在一个有5个主分片的索引中搜索。当我们请求结果的第一页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给请求节点(requesting node),
它再排序这所有的50个结果以选出顶端的10个结果。现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端的10010个结果。
然后请求节点排序这50050个结果并丢弃50040个!可以看到在分布式系统中,排序结果的花费随着分页的深入而成倍增长。这也是为什么网络搜索引擎中任何语句不能返回多于1000个结果的原因。

3.2.6 DSL搜索

Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。
DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现

2020030126

如图我们查询了一个年龄大于10岁,性别为男性的数据

3.2.7 聚合

在Elasticsearch中,支持聚合操作,类似SQL中的group by操作。

2020030127

3.2.8 _bulk操作

在Elasticsearch中,支持批量的插入、修改、删除操作,都是通过_bulk的api完成的。
1
2
3
4
5
6
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...
# 注意每行最后必须有 \n

1、批量插入

2020030130
2020030131

2、批量删除

2020030132
2020030134

3、批量删除

2020030135
2020030136

4、混合操作

2020030137
2020030138

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"took": 5,
"errors": false,
"items": [
{
"update": {
"_index": "eelve",
"_type": "user",
"_id": "2002",
"_version": 2,
"result": "updated",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 7,
"_primary_term": 1,
"status": 200
}
},
{
"delete": {
"_index": "eelve",
"_type": "user",
"_id": "2003",
"_version": 3,
"result": "deleted",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 8,
"_primary_term": 1,
"status": 200
}
}
]
}
整个批量请求需要被加载到接受我们请求节点的内存里,所以请求越大,给其它请求可用的内存就越小。有一个最佳的bulk请求大小。
超过这个大小,性能不再提升而且可能降低。

最佳大小,当然并不是一个固定的数字。它完全取决于你的硬件、你文档的大小和复杂度以及索引和搜索的负载。
幸运的是,这个最佳点(sweetspot)还是容易找到的:试着批量索引标准的文档,随着大小的增长,当性能开始降低,
说明你每个批次的大小太大了。开始的数量可以在1000~5000个文档之间,如果你的文档非常大,可以使用较小的批次。
通常着眼于你请求批次的物理大小是非常有用的。一千个1kB的文档和一千个1MB的文档大不相同。一个好的批次最好保持在5-15MB大小间。

3.2.9 字段映射

前面我们创建的索引以及插入数据,都是由Elasticsearch进行自动判断类型,有些时候我们是需要进行明确字段类型的,否则,自动判断的类型和实际需求是不相符的。

自动判断的规则如下:

SON type Field type
Boolean: true or false “boolean”
Whole number: 123 “long”
Floating point: 123.45 “double”
String, valid date: “2014-09-15” “date”
String: “foo bar” “string”

Elasticsearch中支持的类型如下:

类型 表示的数据类型
String string , text , keyword
Whole number: byte , short , integer , long
Floating point: float , double
Boolean boolean
Date date
string类型在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代。

text 类型,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,
在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。

keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。
keyword类型的字段只能通过精确值搜索到。

2020030140

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"settings": {
"index": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
},
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text"
}
}
}
}

2020030141

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"iio": {
"aliases": {},
"mappings": {
"properties": {
"age": {
"type": "integer"
},
"hobby": {
"type": "text"
},
"mail": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
},
"settings": {
"index": {
"creation_date": "1583052049836",
"number_of_shards": "2",
"number_of_replicas": "0",
"uuid": "CFfnz0C0SnSkgceUONQNEA",
"version": {
"created": "7060099"
},
"provided_name": "iio"
}
}
}
}

注意的是7.x的版本我6.x的版本创建索引不一样,6.x还需要在properties外面用类型包裹,下面给一个示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"settings": {
"index": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
},
"mappings": {
"person": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text"
}
}
}
}
}

肆、注意事项

注意版本差异,具体关注官方。我这边所演示的整个Elastic stack家族的版本都为7.6.0。另外批量操作的时候,如果有其中某一条执行失败的话,并不会影响其他执行正确的结果。


【后面的话】记住Elasticsearch是整个Elastic Stack的核心。具有查询分析、高速度、可扩展性、相关度和弹性,后面我们还会具体实践。另外关于Elasticsearch的还有组合搜索,权重,分词等等还没有实践,等后面实践之后文章会继续更新,可能会写一篇关于Elasticsearch深度使用的文章。


薏米笔记

# hide
Elastic Stack实战之Elasticsearch初体验(一)
Elastic Stack实战之Elasticsearch初体验(二)
  • 文章目录
  • 站点概览
Chillo

Chillo

A human being,who loves football and music.
60 日志
14 分类
42 标签
RSS
GitHub E-Mail
Links
  • 南国薏米
  • 蔚然山庄
  • Github Pages
  • Gitee Pages
  • 坤坤
  • Binge
  • BoBo
  • 克宁
  1. 1. 壹、Elasticsearch介绍
  2. 2. 贰、插件安装
  3. 3. 叁、简单使用
    1. 3.1. 3.1 基本概念
    2. 3.2. 3.2 RESTful API
      1. 3.2.1. 3.2.1 创建非结构化索引
      2. 3.2.2. 3.2.2 插入数据
      3. 3.2.3. 3.2.3 更新数据
      4. 3.2.4. 3.2.4 删除数据
      5. 3.2.5. 3.2.5 搜索数据
      6. 3.2.6. 3.2.6 DSL搜索
      7. 3.2.7. 3.2.7 聚合
      8. 3.2.8. 3.2.8 _bulk操作
      9. 3.2.9. 3.2.9 字段映射
  4. 4. 肆、注意事项
© 2020 南国薏米 | 站点总字数: 369k | 站点阅读时长 ≈ 5:36
博客全站共91.6k字
|
0%