Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎。
ES 介绍
玩“飞花令”游戏时,让游戏参与者说出带“月”字的诗句,我们可以去百度输入“带月字的古诗”,百度就会返回相关的信息。
ES 也是一个类似的搜索引擎,它的作用就是从海量的数据中找到我们所关心的问题,如:
- 带月字的古诗?
- 24 小时内带 connection lost 关键字的日志?
- 某个产品包含卡顿关键字的用户评论?
ES 也能处理数据聚合的问题,如:
- 包含卡顿关键字的用户评论的数量?
- 7 天内接口调用的平均耗时,最小耗时,最大耗时?
ES 实现快速查询的关键就是倒排索引。
正向索引与倒排索引
如果我们需要查找带月的古诗,首先我们要有数据。
如我们提供两首李白的古诗:
《静夜思》
床前明月光,疑是地上霜。举头望明月,低头思故乡。
《玉阶怨》唐·李白
玉阶生白露,夜久侵罗袜。却下水晶帘,玲珑望秋月。
对于一般的数据库,我们常常会把诗名作为索引的键,内容作为值。
这种情况下如果我们查询“静夜思”对应的内容是非常快的。
但是查询带月的诗就慢得多,需要先找到所有诗的内容,然后找其中是否有月。想要快速查询,可以建立一个以“月”为键,诗名为值的索引。
key | value |
---|
床 | 静夜思 |
前 | 静夜思 |
明 | 静夜思 |
月 | 静夜思 玉阶怨 |
如果我们查找带月的古诗就能快速找到“静夜思 玉阶怨” ,然后再根据正向索引就能找到内容。
以内容作为键的索引就叫做倒排索引,也叫反向索引。
搜索引擎的核心就是建立倒排索引。
ES 系统
ES 是基于 Apache Lucene ,Lucene 可以看是一个建立倒排索引的库。ES 基于 Lucence 封装,实现了分布式的搜索引擎,并且所有的操作都提供 rest api。
ES 中的重要概念
在使用 ES 之前,需要先了解以下 ES 中的几个重要概念。
索引库 indices
索引库类似与 mysql 中库(database)的概念,indices 是 index 的复数,意思是有许多索引。
文档 Document
文档就是存入索引中的原始数据,每一条信息就是一个文档。ES 中的文档格式都是 json,每个文档都是一个 json 对象。
字段 field
文档中的属性,一个文档中可以有多个属性,如:
1
2
3
4
| {
"user_name": "123",
"user_password": "111"
}
|
上面这个文档包括 user_name
和 user_password
。
字段数据类型
每个字段都有它的数据类型,如 string
类型,=boolean= 类型。类型指示字段的数据类型及索引动作对字段的操作。
例如一个字符串可以为 text
类型,也可以为 keyword
类型。=text= 类型是为了全文搜索,
keyword
类型是为了索引和排序。在创建字段时需要根据用途选择类型。
所有的数据类型:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
映射 Mapping
映射是定义文档及其包含的字段如何存储和索引的过程。
文档中的每个字段都有它们的数据类型,Mapping 可以定义字段的类型及其它的一些属性。
如:
1
2
3
4
5
6
7
8
9
| {
"mappings": {
"properties": {
"user_name": {
"type": "keyword"
}
}
}
}
|
上面的 mapping 定义了属性 user_name
的类型为 keyword
。
索引模板 Index Template
索引模块定义了索引的相关设置(setting)和映射(Mapping),当创建一个新的索引时直接应用模板快速创建。
搜索
搜索就是将我们的问题以 ES 能够理解的方式向 ES 发出请求,ES 会返回对应的数据, 如:
查询 DSL
一个搜索可以分解成多个查询,要想 ES 能够理解查询请求,就得用 ES 的查询 DSL。
比如下面的查询意思就是 verse
字段中有月的数据
1
2
3
4
5
6
7
| {
"query": {
"match": {
"verse": "月"
}
}
}
|
聚合 Aggregations
聚合操作可以将 ES 中的数据进行统计或度量,如:
这里只是简单介绍,更多的内容可以看官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
ES 实战
ES 是一个比较复杂的分布式系统,但是我们可以在自己的 PC 上体验它的功能。
安装 ES
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html
Windows 就是下载一个压缩包,解压后执行 .\bin\elasticsearch.bat
启动 ES。
ES 服务的默认端口为 9200
,ES 启动后就可以用 rest api 使用 ES。
创建索引
下面创建一个索引来保存古诗。
PUT http://127.0.0.1:9200/poetry
Content-Type: application/json
{
"mappings":
{
"properties":
{
"poetry_name" : { "type" : "keyword" },
"poetry_content" : { "type" : "text" }
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
| {
"acknowledged": true,
"shards_acknowledged": true,
"index": "poetry"
}
// PUT http://127.0.0.1:9200/poetry
// HTTP/1.1 200 OK
// X-elastic-product: Elasticsearch
// Warning: 299 Elasticsearch-7.15.0-79d65f6e357953a5b3cbcc5e2c7c21073d89aa29 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
// content-type: application/json; charset=UTF-8
// content-length: 73
// Request duration: 0.267371s
|
它有两个字段,~poetry_name~ 表示诗名,类型为 keyword,~poetry_content~ 表示诗内容,类型为 text
。
增加文档
一个文档即一条记录,下面向索引中添加文档
POST http://127.0.0.1:9200/poetry/_doc/
Content-Type: application/json
{
"poetry_name" : "静夜思",
"poetry_content" : "床前明月光,疑是地上霜。举头望明月,低头思故乡。"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| {
"_index": "poetry",
"_type": "_doc",
"_id": "GzyMfnwBkpjcizGoE2rW",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
// POST http://127.0.0.1:9200/poetry/_doc/
// HTTP/1.1 201 Created
// Location: /poetry/_doc/GzyMfnwBkpjcizGoE2rW
// X-elastic-product: Elasticsearch
// Warning: 299 Elasticsearch-7.15.0-79d65f6e357953a5b3cbcc5e2c7c21073d89aa29 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
// content-type: application/json; charset=UTF-8
// content-length: 173
// Request duration: 0.010882s
|
POST http://127.0.0.1:9200/poetry/_doc/
Content-Type: application/json
{
"poetry_name" : "玉阶怨",
"poetry_content" : "玉阶生白露,夜久侵罗袜。却下水晶帘,玲珑望秋月。"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| {
"_index": "poetry",
"_type": "_doc",
"_id": "HDyMfnwBkpjcizGoPmpr",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
// POST http://127.0.0.1:9200/poetry/_doc/
// HTTP/1.1 201 Created
// Location: /poetry/_doc/HDyMfnwBkpjcizGoPmpr
// X-elastic-product: Elasticsearch
// Warning: 299 Elasticsearch-7.15.0-79d65f6e357953a5b3cbcc5e2c7c21073d89aa29 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
// content-type: application/json; charset=UTF-8
// content-length: 173
// Request duration: 0.010298s
|
查询带月的诗
GET http://127.0.0.1:9200/poetry/_search/
Content-Type: application/json
{
"query" :
{
"term" :
{
"poetry_content" :
{
"value" : "月"
}
}
}
}
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
41
42
43
44
45
46
| {
"took": 156,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.25069216,
"hits": [
{
"_index": "poetry",
"_type": "_doc",
"_id": "GzyMfnwBkpjcizGoE2rW",
"_score": 0.25069216,
"_source": {
"poetry_name": "静夜思",
"poetry_content": "床前明月光,疑是地上霜。举头望明月,低头思故乡。"
}
},
{
"_index": "poetry",
"_type": "_doc",
"_id": "HDyMfnwBkpjcizGoPmpr",
"_score": 0.18232156,
"_source": {
"poetry_name": "玉阶怨",
"poetry_content": "玉阶生白露,夜久侵罗袜。却下水晶帘,玲珑望秋月。"
}
}
]
}
}
// GET http://127.0.0.1:9200/poetry/_search/
// HTTP/1.1 200 OK
// X-elastic-product: Elasticsearch
// Warning: 299 Elasticsearch-7.15.0-79d65f6e357953a5b3cbcc5e2c7c21073d89aa29 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
// content-type: application/json; charset=UTF-8
// content-length: 625
// Request duration: 0.161839s
|
带月的诗的数量
GET http://127.0.0.1:9200/poetry/_count/
Content-Type: application/json
{
"query" :
{
"term" :
{
"poetry_content" :
{
"value" : "月"
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {
"count": 2,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
}
}
// GET http://127.0.0.1:9200/poetry/_count/
// HTTP/1.1 200 OK
// X-elastic-product: Elasticsearch
// Warning: 299 Elasticsearch-7.15.0-79d65f6e357953a5b3cbcc5e2c7c21073d89aa29 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.15/security-minimal-setup.html to enable security."
// content-type: application/json; charset=UTF-8
// content-length: 71
// Request duration: 0.006464s
|
参考链接:
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
https://zhuanlan.zhihu.com/p/62892586