📚 更新 ES 文档

pull/19/head
dunwu 2022-02-22 21:01:01 +08:00
parent fa44ac5ab0
commit 0e9ded6812
16 changed files with 1896 additions and 715 deletions

View File

@ -71,12 +71,20 @@
#### [Elasticsearch](docs/nosql/elasticsearch) 📚
> Elasticsearch 是一个基于 Lucene 的搜索和数据分析工具它提供了一个分布式服务。Elasticsearch 是遵从 Apache 开源条款的一款开源产品,是当前主流的企业级搜索引擎。
- [Elasticsearch 面试总结](docs/nosql/elasticsearch/elasticsearch-interview.md) 💯
- [Elasticsearch 简介](docs/nosql/elasticsearch/Elasticsearch简介.md)
- [Elasticsearch 快速入门](docs/nosql/elasticsearch/Elasticsearch快速入门.md)
- [Elasticsearch 基本概念](docs/nosql/elasticsearch/Elasticsearch基本概念.md)
- [Elasticsearch 简介](docs/nosql/elasticsearch/Elasticsearch简介.md)
- [Elasticsearch Rest API](docs/nosql/elasticsearch/ElasticsearchRestApi.md)
- [Elasticsearch 索引管理](docs/nosql/elasticsearch/Elasticsearch索引管理.md)
- [Elasticsearch 查询](docs/nosql/elasticsearch/Elasticsearch查询.md)
- [Elasticsearch 高亮](docs/nosql/elasticsearch/Elasticsearch高亮.md)
- [Elasticsearch 排序](docs/nosql/elasticsearch/Elasticsearch排序.md)
- [Elasticsearch 聚合](docs/nosql/elasticsearch/Elasticsearch聚合.md)
- [Elasticsearch 分析器](docs/nosql/elasticsearch/Elasticsearch分析器.md)
- [Elasticsearch 运维](docs/nosql/elasticsearch/Elasticsearch运维.md)
- [Elasticsearch 性能优化](docs/nosql/elasticsearch/Elasticsearch性能优化.md)
#### HBase

View File

@ -70,12 +70,20 @@ footer: CC-BY-SA-4.0 Licensed | Copyright © 2018-Now Dunwu
#### [Elasticsearch](nosql/elasticsearch) 📚
> Elasticsearch 是一个基于 Lucene 的搜索和数据分析工具它提供了一个分布式服务。Elasticsearch 是遵从 Apache 开源条款的一款开源产品,是当前主流的企业级搜索引擎。
- [Elasticsearch 面试总结](nosql/elasticsearch/elasticsearch-interview.md) 💯
- [Elasticsearch 简介](nosql/elasticsearch/Elasticsearch简介.md)
- [Elasticsearch 快速入门](nosql/elasticsearch/Elasticsearch快速入门.md)
- [Elasticsearch 基本概念](nosql/elasticsearch/Elasticsearch基本概念.md)
- [Elasticsearch 简介](nosql/elasticsearch/Elasticsearch简介.md)
- [Elasticsearch Rest API](nosql/elasticsearch/ElasticsearchRestApi.md)
- [Elasticsearch 索引管理](nosql/elasticsearch/Elasticsearch索引管理.md)
- [Elasticsearch 查询](nosql/elasticsearch/Elasticsearch查询.md)
- [Elasticsearch 高亮](nosql/elasticsearch/Elasticsearch高亮.md)
- [Elasticsearch 排序](nosql/elasticsearch/Elasticsearch排序.md)
- [Elasticsearch 聚合](nosql/elasticsearch/Elasticsearch聚合.md)
- [Elasticsearch 分析器](nosql/elasticsearch/Elasticsearch分析器.md)
- [Elasticsearch 运维](nosql/elasticsearch/Elasticsearch运维.md)
- [Elasticsearch 性能优化](nosql/elasticsearch/Elasticsearch性能优化.md)
#### HBase
@ -86,9 +94,13 @@ footer: CC-BY-SA-4.0 Licensed | Copyright © 2018-Now Dunwu
- [HBase 应用](https://github.com/dunwu/bigdata-tutorial/blob/master/docs/hbase/HBase应用.md)
- [HBase 运维](https://github.com/dunwu/bigdata-tutorial/blob/master/docs/hbase/HBase运维.md)
#### MongoDB
#### [MongoDB](nosql/mongodb) 📚
> [MongoDB](nosql/mongodb) 📚
> MongoDB 是一个基于文档的分布式数据库,由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
>
> MongoDB 是一个介于关系型数据库和非关系型数据库之间的产品。它是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。
>
> MongoDB 最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
- [MongoDB 应用指南](nosql/mongodb/mongodb-quickstart.md)
- [MongoDB 聚合操作](nosql/mongodb/mongodb-aggregation.md)
@ -106,39 +118,56 @@ footer: CC-BY-SA-4.0 Licensed | Copyright © 2018-Now Dunwu
## 📚 资料
- **Mysql**
- **官方**
### Mysql 资料
- **官方**
- [Mysql 官网](https://www.mysql.com/)
- [Mysql 官方文档](https://dev.mysql.com/doc/refman/8.0/en/)
- [Mysql 官方文档之命令行客户端](https://dev.mysql.com/doc/refman/8.0/en/mysql.html)
- **书籍**
- **书籍**
- [《高性能 MySQL》](https://book.douban.com/subject/23008813/) - 经典,适合 DBA 或作为开发者的参考手册
- [《MySQL 必知必会》](https://book.douban.com/subject/3354490/) - 适合入门者
- **教程**
- **教程**
- [runoob.com MySQL 教程](http://www.runoob.com/mysql/mysql-tutorial.html) - 入门级 SQL 教程
- [mysql-tutorial](https://github.com/jaywcjlove/mysql-tutorial)
- **更多资源**
- **更多资源**
- [awesome-mysql](https://github.com/jobbole/awesome-mysql-cn)
- **Redis**
- **官网**
### Redis 资料
- **官网**
- [Redis 官网](https://redis.io/)
- [Redis github](https://github.com/antirez/redis)
- [Redis 官方文档中文版](http://redis.cn/)
- [Redis 命令参考](http://redisdoc.com/)
- **书籍**
- **书籍**
- [《Redis 实战》](https://item.jd.com/11791607.html)
- [《Redis 设计与实现》](https://item.jd.com/11486101.html)
- **源码**
- **源码**
- [《Redis 实战》配套 Python 源码](https://github.com/josiahcarlson/redis-in-action)
- **资源汇总**
- **资源汇总**
- [awesome-redis](https://github.com/JamzyWang/awesome-redis)
- **Redis Client**
- **Redis Client**
- [spring-data-redis 官方文档](https://docs.spring.io/spring-data/redis/docs/1.8.13.RELEASE/reference/html/)
- [redisson 官方文档(中文,略有滞后)](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95)
- [redisson 官方文档(英文)](https://github.com/redisson/redisson/wiki/Table-of-Content)
- [CRUG | Redisson PRO vs. Jedis: Which Is Faster? 翻译](https://www.jianshu.com/p/82f0d5abb002)
- [redis 分布锁 Redisson 性能测试](https://blog.csdn.net/everlasting_188/article/details/51073505)
### MongoDB 资料
- **官方**
- [MongoDB 官网](https://www.mongodb.com/)
- [MongoDB Github](https://github.com/mongodb/mongo)
- [MongoDB 官方免费教程](https://university.mongodb.com/)
- **教程**
- [MongoDB 教程](https://www.runoob.com/mongodb/mongodb-tutorial.html)
- [MongoDB 高手课](https://time.geekbang.org/course/intro/100040001)
- **数据**
- [mongodb-json-files](https://github.com/ozlerhakan/mongodb-json-files)
- **文章**
- [Introduction to MongoDB](https://www.slideshare.net/mdirolf/introduction-to-mongodb)
## 🚪 传送
◾ 🏠 [DB-TUTORIAL 首页](https://github.com/dunwu/db-tutorial) ◾ 🎯 [我的博客](https://github.com/dunwu/blog) ◾

View File

@ -22,7 +22,7 @@
- [Elasticsearch 面试总结](elasticsearch/elasticsearch-interview.md) 💯
- [Elasticsearch 简介](elasticsearch/Elasticsearch简介.md)
- [Elasticsearch 快速入门](elasticsearch/Elasticsearch快速入门.md)
- [Elasticsearch 基本概念](elasticsearch/Elasticsearch基本概念.md)
- [Elasticsearch 基本概念](elasticsearch/Elasticsearch索引管理.md)
- [Elasticsearch Rest API](elasticsearch/ElasticsearchRestApi.md)
- [Elasticsearch 运维](elasticsearch/Elasticsearch运维.md)

View File

@ -5,35 +5,68 @@
> [Elasticsearch](https://github.com/elastic/elasticsearch) 基于搜索库 [Lucene](https://github.com/apache/lucene-solr) 开发。ElasticSearch 隐藏了 Lucene 的复杂性,提供了简单易用的 REST API / Java API 接口(另外还有其他语言的 API 接口)。
>
> _以下简称 ES_
>
> REST API 最详尽的文档应该参考:[ES 官方 REST API](https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html)
## 索引 API
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. ElasticSearch Rest API 语法格式](#1-elasticsearch-rest-api-语法格式)
- [2. 索引 API](#2-索引-api)
- [2.1. 创建索引](#21-创建索引)
- [2.2. 删除索引](#22-删除索引)
- [2.3. 查看索引](#23-查看索引)
- [2.4. 索引别名](#24-索引别名)
- [2.5. 打开/关闭索引](#25-打开关闭索引)
- [3. 文档](#3-文档)
- [3.1. 创建文档](#31-创建文档)
- [3.2. 删除文档](#32-删除文档)
- [3.3. 更新文档](#33-更新文档)
- [3.4. 查询文档](#34-查询文档)
- [3.5. 全文搜索](#35-全文搜索)
- [3.6. 逻辑运算](#36-逻辑运算)
- [3.7. 批量执行](#37-批量执行)
- [3.8. 批量读取](#38-批量读取)
- [3.9. 批量查询](#39-批量查询)
- [3.10. URI Search 查询语义](#310-uri-search-查询语义)
- [3.11. Request Body & DSL](#311-request-body--dsl)
- [4. 集群 API](#4-集群-api)
- [4.1. 集群健康 API](#41-集群健康-api)
- [4.2. 集群状态 API](#42-集群状态-api)
- [5. 节点 API](#5-节点-api)
- [6. 分片 API](#6-分片-api)
- [7. 监控 API](#7-监控-api)
- [8. 参考资料](#8-参考资料)
<!-- /TOC -->
## 1. ElasticSearch Rest API 语法格式
向 Elasticsearch 发出的请求的组成部分与其它普通的 HTTP 请求是一样的:
```bash
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
```
- `VERB`HTTP 方法,支持:`GET`, `POST`, `PUT`, `HEAD`, `DELETE`
- `PROTOCOL`http 或者 https 协议(只有在 Elasticsearch 前面有 https 代理的时候可用)
- `HOST`Elasticsearch 集群中的任何一个节点的主机名,如果是在本地的节点,那么就叫 localhost
- `PORT`Elasticsearch HTTP 服务所在的端口,默认为 9200 PATH API 路径(例如\_count 将返回集群中文档的数量),
- `PATH`:可以包含多个组件,例如 `_cluster/stats` 或者 `_nodes/stats/jvm`
- `QUERY_STRING`:一些可选的查询请求参数,例如?pretty 参数将使请求返回更加美观易读的 JSON 数据
- `BODY`:一个 JSON 格式的请求主体(如果请求需要的话)
## 2. 索引 API
> 参考资料:[Elasticsearch 官方之 cat 索引 API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-indices.html)
### 创建索引
### 2.1. 创建索引
新建 Index可以直接向 ES 服务器发出 `PUT` 请求。
1直接创建索引
```bash
curl -X POST 'localhost:9200/user'
```
服务器返回一个 JSON 对象,里面的 `acknowledged` 字段表示操作成功。
```javascript
{"acknowledged":true,"shards_acknowledged":true,"index":"user"}
```
2创建索引时指定配置
语法格式:
```bash
$ curl -X PUT /my_index
PUT /my_index
{
"settings": { ... any settings ... },
"mappings": {
@ -47,15 +80,21 @@ $ curl -X PUT /my_index
示例:
```bash
$ curl -X PUT -H 'Content-Type: application/json' 'localhost:9200/user' -d '
PUT /user
{
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
}'
}
```
服务器返回一个 JSON 对象,里面的 `acknowledged` 字段表示操作成功。
```javascript
{"acknowledged":true,"shards_acknowledged":true,"index":"user"}
```
如果你想禁止自动创建索引,可以通过在 `config/elasticsearch.yml` 的每个节点下添加下面的配置:
@ -64,12 +103,12 @@ $ curl -X PUT -H 'Content-Type: application/json' 'localhost:9200/user' -d '
action.auto_create_index: false
```
### 删除索引
### 2.2. 删除索引
然后,我们可以通过发送 `DELETE` 请求,删除这个 Index。
```bash
curl -X DELETE 'localhost:9200/user'
DELETE /user
```
删除多个索引
@ -79,7 +118,7 @@ DELETE /index_one,index_two
DELETE /index_*
```
### 查看索引
### 2.3. 查看索引
可以通过 GET 请求查看索引信息
@ -110,7 +149,45 @@ GET /_cat/indices/kibana*?pri&v&h=health,index,pri,rep,docs.count,mt
GET /_cat/indices?v&h=i,tm&s=tm:desc
```
### 打开/关闭索引
### 2.4. 索引别名
ES 的索引别名就是给一个索引或者多个索引起的另一个名字,典型的应用场景是针对索引使用的平滑切换。
首先,创建索引 my_index然后将别名 my_alias 指向它,示例如下:
```bash
PUT /my_index
PUT /my_index/_alias/my_alias
```
也可以通过如下形式:
```bash
POST /_aliases
{
"actions": [
{ "add": { "index": "my_index", "alias": "my_alias" }}
]
}
```
也可以在一次请求中增加别名和移除别名混合使用:
```bash
POST /_aliases
{
"actions": [
{ "remove": { "index": "my_index", "alias": "my_alias" }}
{ "add": { "index": "my_index_v2", "alias": "my_alias" }}
]
}
```
> 需要注意的是,如果别名与索引是一对一的,使用别名索引文档或者查询文档是可以的,但是如果别名和索引是一对多的,使用别名会发生错误,因为 ES 不知道把文档写入哪个索引中去或者从哪个索引中读取文档。
ES 索引别名有个典型的应用场景是平滑切换,更多细节可以查看 [ElasticsearchES索引零停机无需重启无缝平滑切换的方法](https://www.knowledgedict.com/tutorial/elasticsearch-index-smooth-shift.html)。
### 2.5. 打开/关闭索引
通过在 `POST` 中添加 `_close``_open` 可以打开、关闭索引。
@ -123,9 +200,9 @@ POST kibana_sample_data_ecommerce/_open
POST kibana_sample_data_ecommerce/_close
```
## 文档
## 3. 文档
```
```bash
############Create Document############
#create document. 自动生成 _id
POST users/_doc
@ -279,7 +356,7 @@ DELETE test
DELETE test2
```
### 创建文档
### 3.1. 创建文档
#### 指定 ID
@ -323,7 +400,7 @@ POST /user/_doc
}
```
### 删除文档
### 3.2. 删除文档
语法格式:
@ -337,7 +414,7 @@ DELETE /_index/_doc/_id
DELETE /user/_doc/1
```
### 更新文档
### 3.3. 更新文档
#### 先删除,再写入
@ -377,7 +454,7 @@ POST /user/_update/1
}
```
### 查询文档
### 3.4. 查询文档
#### 指定 ID 查询
@ -470,7 +547,7 @@ $ curl 'localhost:9200/user/admin/_search?pretty'
返回的记录中,每条记录都有一个`_score`字段,表示匹配的程序,默认是按照这个字段降序排列。
### 全文搜索
### 3.5. 全文搜索
ES 的查询非常特别,使用自己的[查询语法](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl.html),要求 GET 请求带有数据体。
@ -537,7 +614,7 @@ $ curl 'localhost:9200/user/admin/_search' -d '
上面代码指定,从位置 1 开始(默认是从位置 0 开始),只返回一条结果。
### 逻辑运算
### 3.6. 逻辑运算
如果有多个搜索关键字, Elastic 认为它们是`or`关系。
@ -566,7 +643,7 @@ $ curl -H 'Content-Type: application/json' 'localhost:9200/user/admin/_search?pr
}'
```
### 批量执行
### 3.7. 批量执行
支持在一次 API 调用中,对不同的索引进行操作
@ -594,7 +671,7 @@ POST _bulk
> 说明:上面的示例如果执行多次,执行结果都不一样。
### 批量读取
### 3.8. 批量读取
读多个索引
@ -656,7 +733,7 @@ GET /_mget
}
```
### 批量查询
### 3.9. 批量查询
```bash
POST kibana_sample_data_ecommerce/_msearch
@ -666,7 +743,7 @@ POST kibana_sample_data_ecommerce/_msearch
{"query" : {"match_all" : {}},"size":2}
```
### URI Search 查询语义
### 3.10. URI Search 查询语义
Elasticsearch URI Search 遵循 QueryString 查询语义,其形式如下:
@ -815,7 +892,7 @@ GET /movies/_search?q=title:"Lord Rings"~2
}
```
### Request Body & DSL
### 3.11. Request Body & DSL
Elasticsearch 除了 URI Search 查询方式,还支持将查询语句通过 Http Request Body 发起查询。
@ -955,7 +1032,7 @@ POST movies/_search
}
```
## 集群 API
## 4. 集群 API
> [Elasticsearch 官方之 Cluster API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html)
@ -999,7 +1076,7 @@ GET /_nodes/ra*:2
GET /_nodes/ra*:2*
```
### 集群健康 API
### 4.1. 集群健康 API
```bash
GET /_cluster/health
@ -1008,7 +1085,7 @@ GET /_cluster/health/kibana_sample_data_ecommerce,kibana_sample_data_flights
GET /_cluster/health/kibana_sample_data_flights?level=shards
```
### 集群状态 API
### 4.2. 集群状态 API
集群状态 API 返回表示整个集群状态的元数据。
@ -1016,7 +1093,7 @@ GET /_cluster/health/kibana_sample_data_flights?level=shards
GET /_cluster/state
```
## 节点 API
## 5. 节点 API
> [Elasticsearch 官方之 cat Nodes API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-nodes.html)——返回有关集群节点的信息。
@ -1027,7 +1104,7 @@ GET /_cat/nodes?v=true
GET /_cat/nodes?v=true&h=id,ip,port,v,m
```
## 分片 API
## 6. 分片 API
> [Elasticsearch 官方之 cat Shards API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-shards.html)——shards 命令是哪些节点包含哪些分片的详细视图。它会告诉你它是主还是副本、文档数量、它在磁盘上占用的字节数以及它所在的节点。
@ -1040,7 +1117,46 @@ GET /_cat/shards/my-index-*
GET /_cat/shards?h=index,shard,prirep,state,unassigned.reason
```
## 参考资料
## 7. 监控 API
Elasticsearch 中集群相关的健康、统计等相关的信息都是围绕着 `cat` API 进行的。
通过 GET 请求发送 cat下面列出了所有可用的 API
```bash
GET /_cat
=^.^=
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/tasks
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/thread_pool/{thread_pools}
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
/_cat/templates
```
## 8. 参考资料
- **官方**
- [Elasticsearch 官网](https://www.elastic.co/cn/products/elasticsearch)

View File

@ -0,0 +1,407 @@
# Elasticsearch 分析器
在 ES 中,不管是索引任务还是搜索工作,都需要使用 analyzer分析器。分析器分为**内置分析器**和**自定义的分析器**。
分析器进一步由**字符过滤器****Character Filters**)、**分词器****Tokenizer**)和**词元过滤器****Token Filters**)三部分组成。它的执行顺序如下:
**_character filters_** -> **_tokenizer_** -> **_token filters_**
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 字符过滤器Character Filters](#1-字符过滤器character-filters)
- [1.1. HTML strip character filter](#11-html-strip-character-filter)
- [1.2. Mapping character filter](#12-mapping-character-filter)
- [1.3. Pattern Replace character filter](#13-pattern-replace-character-filter)
- [2. 分词器Tokenizer](#2-分词器tokenizer)
- [2.1. elasticsearch-plugin 使用](#21-elasticsearch-plugin-使用)
- [2.2. elasticsearch-analysis-ik 安装](#22-elasticsearch-analysis-ik-安装)
- [2.3. elasticsearch-analysis-ik 使用](#23-elasticsearch-analysis-ik-使用)
- [3. 词元过滤器Token Filters](#3-词元过滤器token-filters)
- [3.1. 同义词](#31-同义词)
- [4. 参考资料](#4-参考资料)
<!-- /TOC -->
## 1. 字符过滤器Character Filters
character filter 的输入是原始的文本 text如果配置了多个它会按照配置的顺序执行目前 ES 自带的 character filter 主要由如下 3 类:
1. html strip character filter从文本中剥离 HTML 元素,并用其解码值替换 HTML 实体(如,将 **_`amp;`_** 替换为 **_``_**)。
2. mapping character filter自定义一个 map 映射,可以进行一些自定义的替换,如常用的大写变小写也可以在该环节设置。
3. pattern replace character filter使用 java 正则表达式来匹配应替换为指定替换字符串的字符,此外,替换字符串可以引用正则表达式中的捕获组。
### 1.1. HTML strip character filter
HTML strip 如下示例:
```bash
GET /_analyze
{
"tokenizer": "keyword",
"char_filter": [
"html_strip"
],
"text": "<p>I&apos;m so <b>happy</b>!</p>"
}
```
经过 **_`html_strip`_** 字符过滤器处理后,输出如下:
```
[ \nI'm so happy!\n ]
```
### 1.2. Mapping character filter
Mapping character filter 接收键和值映射key => value作为配置参数每当在预处理过程中遇到与键值映射中的键相同的字符串时就会使用该键对应的值去替换它。
原始文本中的字符串和键值映射中的键的匹配是贪心的,在对给定的文本进行预处理过程中如果配置的键值映射存在包含关系,会优先**匹配最长键**。同样也可以用空字符串进行替换。
mapping char_filter 不像 html_strip 那样拆箱即可用,必须先进行配置才能使用,它有两个属性可以配置:
| 参数名称 | 参数说明 |
| :-------------------- | :--------------------------------------------------------------------------------------------- |
| **_`mappings`_** | 一组映射,每个元素的格式为 _key => value_。 |
| **_`mappings_path`_** | 一个相对或者绝对的文件路径,指向一个每行包含一个 _key =>value_ 映射的 UTF-8 编码文本映射文件。 |
mapping char_filter 示例如下:
```bash
GET /_analyze
{
"tokenizer": "keyword",
"char_filter": [
{
"type": "mapping",
"mappings": [
"٠ => 0",
"١ => 1",
"٢ => 2",
"٣ => 3",
"٤ => 4",
"٥ => 5",
"٦ => 6",
"٧ => 7",
"٨ => 8",
"٩ => 9"
]
}
],
"text": "My license plate is ٢٥٠١٥"
}
```
分析结果如下:
```
[ My license plate is 25015 ]
```
### 1.3. Pattern Replace character filter
Pattern Replace character filter 支持如下三个参数:
| 参数名称 | 参数说明 |
| :------------------ | :----------------------------------------------------------------------------- |
| **_`pattern`_** | 必填参数,一个 java 的正则表达式。 |
| **_`replacement`_** | 替换字符串,可以使用 **_`$1 ... $9`_** 语法来引用捕获组。 |
| **_`flags`_** | Java 正则表达式的标志,具体参考 java 的 java.util.regex.Pattern 类的标志属性。 |
如将输入的 text 中大于一个的空格都转变为一个空格,在 settings 时,配置示例如下:
```bash
"char_filter": {
"multi_space_2_one": {
"pattern": "[ ]+",
"type": "pattern_replace",
"replacement": " "
},
...
}
```
## 2. 分词器Tokenizer
tokenizer 即分词器,也是 analyzer 最重要的组件,它对文本进行分词;**一个 analyzer 必需且只可包含一个 tokenizer**。
ES 自带默认的分词器是 standard tokenizer标准分词器提供基于语法的分词基于 Unicode 文本分割算法),并且适用于大多数语言。
此外有很多第三方的分词插件,如中文分词界最经典的 ik 分词器,它对应的 tokenizer 分为 ik_smart 和 ik_max_word一个是智能分词针对搜索侧一个是全切分词针对索引侧
ES 默认提供的分词器 standard 对中文分词不优化,效果差,一般会安装第三方中文分词插件,通常首先 [elasticsearch-analysis-ik](https://github.com/medcl/elasticsearch-analysis-ik) 插件,它其实是 ik 针对的 ES 的定制版。
### 2.1. elasticsearch-plugin 使用
在安装 elasticsearch-analysis-ik 第三方之前,我们首先要了解 es 的插件管理工具 **_`elasticsearch-plugin`_** 的使用。
现在的 elasticsearch 安装完后,在安装目录的 bin 目录下会存在 elasticsearch-plugin 命令工具,用它来对 es 插件进行管理。
```
bin/elasticsearch-plugin
```
其实该命令的是软连接,原始路径是:
```
libexec/bin/elasticsearch-plugin
```
再进一步看脚本代码,你会发现,它是通过 **_`elasticsearch-cli`_** 执行 `libexec/lib/tools/plugin-cli/elasticsearch-plugin-cli-x.x.x.jar`
但一般使用者了解 elasticsearch-plugin 命令使用就可:
```bash
# 安装指定的插件到当前 ES 节点中
elasticsearch-plugin install {plugin_url}
# 显示当前 ES 节点已经安装的插件列表
elasticsearch-plugin list
# 删除已安装的插件
elasticsearch-plugin remove {plugin_name}
```
> 在安装插件时,要保证安装的插件与 ES 版本一致。
### 2.2. elasticsearch-analysis-ik 安装
在确定要安装的 ik 版本之后,执行如下命令:
```bash
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v{X.X.X}/elasticsearch-analysis-ik-{X.X.X}.zip
```
执行完安装命令后,我们会发现在 plugins 中多了 analysis-ik 目录,这里面主要存放的是源码 jar 包,此外,在 config 文件里也多了 analysis-ik 目录,里面主要是 ik 相关的配置,如 IKAnalyzer.cfg.xml 配置、词典文件等。
```bash
# 两个新增目录路径
libexec/plugins/analysis-ik/
libexec/config/analysis-ik/
```
### 2.3. elasticsearch-analysis-ik 使用
ES 5.X 版本开始安装完的 elasticsearch-analysis-ik 提供了两个分词器,分别对应名称是 **_ik_max_word_****_ik_smart_**ik_max_word 是索引侧的分词器走全切模式ik_smart 是搜索侧的分词器,走智能分词,属于搜索模式。
#### 索引 mapping 设置
安装完 elasticsearch-analysis-ik 后我们可以指定索引及指定字段设置可用的分析器analyzer示例如下
```json
{
"qa": {
"mappings": {
"qa": {
"_all": {
"enabled": false
},
"properties": {
"question": {
"type": "text",
"store": true,
"similarity": "BM25",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"answer": {
"type": "text",
"store": false,
"similarity": "BM25",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
...
}
}
}
}
}
```
如上示例中analyzer 指定 ik_max_word即索引侧使用 ik 全切模式search_analyzer 设置 ik_smart即搜索侧使用 ik 智能分词模式。
#### 查看 ik 分词结果
es 提供了查看分词结果的 api **`analyze`**,具体示例如下:
```bash
GET {index}/_analyze
{
"analyzer" : "ik_smart",
"text" : "es 中文分词器安装"
}
```
输出如下:
```json
{
"tokens": [
{
"token": "es",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 0
},
{
"token": "中文",
"start_offset": 3,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
},
{
"token": "分词器",
"start_offset": 5,
"end_offset": 8,
"type": "CN_WORD",
"position": 2
},
{
"token": "安装",
"start_offset": 8,
"end_offset": 10,
"type": "CN_WORD",
"position": 3
}
]
}
```
#### elasticsearch-analysis-ik 自定义词典
elasticsearch-analysis-ik 本质是 ik 分词器,使用者根据实际需求可以扩展自定义的词典,具体主要分为如下 2 大类,每类又分为本地配置和远程配置 2 种:
1. 自定义扩展词典;
2. 自定义扩展停用词典;
elasticsearch-analysis-ik 配置文件为 `IKAnalyzer.cfg.xml`,它位于 `libexec/config/analysis-ik` 目录下,具体配置结构如下:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict"></entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
```
> 当然,如果开发者认为 ik 默认的词表有问题,也可以进行调整,文件都在 `libexec/config/analysis-ik` 下,如 main.dic 为主词典stopword.dic 为停用词表。
## 3. 词元过滤器Token Filters
token filters 叫词元过滤器,或词项过滤器,对 tokenizer 分出的词进行过滤处理。常用的有转小写、停用词处理、同义词处理等等。**一个 analyzer 可包含 0 个或多个词项过滤器,按配置顺序进行过滤**。
以同义词过滤器的使用示例,具体如下:
```bash
PUT /test_index
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "standard",
"filter": [ "my_stop", "synonym" ]
}
},
"filter": {
"my_stop": {
"type": "stop",
"stopwords": [ "bar" ]
},
"synonym": {
"type": "synonym",
"lenient": true,
"synonyms": [ "foo, bar => baz" ]
}
}
}
}
}
}
```
### 3.1. 同义词
Elasticsearch 同义词通过专有的同义词过滤器synonym token filter来进行工作它允许在分析analysis过程中方便地处理同义词一般是通过配置文件配置同义词。此外同义词可以再建索引时index-time synonyms或者检索时search-time synonyms使用。
#### 同义词synonym配置语法
如上例子所示es 同义词配置的 filter 语法具体如下选项:
- **_`type`_**:指定 synonym表示同义词 filter
- **_`synonyms_path`_**:指定同义词配置文件路径;
- **`expand`**:该参数决定映射行为的模式,默认为 true表示扩展模式具体示例如下
- 当 **`expand == true`** 时,
```
ipod, i-pod, i pod
```
等价于:
```
ipod, i-pod, i pod => ipod, i-pod, i pod
```
**_`expand == false`_** 时,
```
ipod, i-pod, i pod
```
仅映射第一个单词,等价于:
```
ipod, i-pod, i pod => ipod
```
- **_`lenient`_**:如果值为 true 时,遇到那些无法解析的同义词规则时,忽略异常。默认为 false。
#### 同义词文档格式
elasticsearch 的同义词有如下两种形式:
- 单向同义词:
```
ipod, i-pod, i pod => ipod
```
- 双向同义词:
```
马铃薯, 土豆, potato
```
单向同义词不管索引还是检索时,箭头左侧的词都会映射成箭头右侧的词;
双向同义词是索引时,都建立同义词的倒排索引,检索时,同义词之间都会进行倒排索引的匹配。
> 同义词的文档化时,需要注意的是,同一个词在不同的同义词关系中出现时,其它同义词之间不具有传递性,这点需要注意。
假设如上示例中,如果“马铃薯”和其它两个同义词分成两行写:
```
马铃薯,土豆
马铃薯,potato
```
此时elasticsearch 中不会将“土豆”和“potato”视为同义词关系所以多个同义词要写在一起这往往是开发中经常容易疏忽的点。
## 4. 参考资料
- [Elasticsearch 教程](https://www.knowledgedict.com/tutorial/elasticsearch-intro.html)

View File

@ -1,521 +0,0 @@
# Elasticsearch 基本概念
## 文档
Elasticsearch 是面向文档的,文档是所有可搜索数据的最小单位。
Elasticsearch 使用 [_JSON_](http://en.wikipedia.org/wiki/Json) 作为文档的序列化格式。
每个文档都有一个 Unique ID
- 用户可以自己指定
- 或通过 Elasticsearch 自动生成
### 文档的元数据
一个文档不仅仅包含它的数据 ,也包含**元数据** —— 有关文档的信息。
- `_index`:文档在哪存放
- `_type`:文档表示的对象类别
- `_id`:文档唯一标识
- `_source`:文档的原始 Json 数据
- `_all`:整合所有字段内容到该字段,已被废除
- `_version`:文档的版本信息
- `_score`:相关性打分
示例:
```json
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": ["sports", "music"]
}
}
```
## 索引
索引在不同语境,有着不同的含义
- 索引(名词):一个 **索引** 类似于传统关系数据库中的一个 **数据库** ,是一个存储关系型文档的容器。 索引 (_index_) 的复数词为 indices 或 indexes 。索引实际上是指向一个或者多个**物理分片**的**逻辑命名空间** 。
- 索引(动词):索引一个文档 就是存储一个文档到一个 _索引_ (名词)中以便被检索和查询。这非常类似于 SQL 语句中的 `INSERT` 关键词,除了文档已存在时,新文档会替换旧文档情况之外。
- 倒排索引:关系型数据库通过增加一个索引比如一个 B 树索引到指定的列上以便提升数据检索速度。Elasticsearch 和 Lucene 使用了一个叫做 **倒排索引** 的结构来达到相同的目的。
索引的 Mapping 和 Setting
- **`Mapping`** 定义文档字段的类型
- **`Setting`** 定义不同的数据分布
示例:
```json
{
"settings": { ... any settings ... },
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
...
}
}
```
### 倒排索引
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220108215559.PNG)
### index template
**`index template`**(索引模板)帮助用户设定 Mapping 和 Setting并按照一定的规则自动匹配到新创建的索引之上。
- 模板仅在一个索引被创建时,才会产生作用。修改模板不会影响已创建的索引。
- 你可以设定多个索引模板,这些设置会被 merge 在一起。
- 你可以指定 order 的数值,控制 merge 的过程。
当新建一个索引时
- 应用 ES 默认的 Mapping 和 Setting
- 应用 order 数值低的 index template 中的设定
- 应用 order 数值高的 index template 中的设定,之前的设定会被覆盖
- 应用创建索引是,用户所指定的 Mapping 和 Setting并覆盖之前模板中的设定。
示例:创建默认索引模板
```bash
PUT _template/template_default
{
"index_patterns": ["*"],
"order": 0,
"version": 1,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
PUT /_template/template_test
{
"index_patterns": ["test*"],
"order": 1,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 2
},
"mappings": {
"date_detection": false,
"numeric_detection": true
}
}
# 查看索引模板
GET /_template/template_default
GET /_template/temp*
#写入新的数据index以test开头
PUT testtemplate/_doc/1
{
"someNumber": "1",
"someDate": "2019/01/01"
}
GET testtemplate/_mapping
GET testtemplate/_settings
PUT testmy
{
"settings":{
"number_of_replicas":5
}
}
PUT testmy/_doc/1
{
"key": "value"
}
GET testmy/_settings
DELETE testmy
DELETE /_template/template_default
DELETE /_template/template_test
```
### dynamic template
- 根据 ES 识别的数据类型,结合字段名称,来动态设定字段类型
- 所有的字符串类型都设定成 Keyword或者关闭 keyword 字段。
- is 开头的字段都设置成 boolean
- long_ 开头的都设置成 long 类型
- dynamic template 是定义在某个索引的 Mapping 中
- template 有一个名称
- 匹配规则是一个数组
- 为匹配到字段设置 Mapping
示例:
```bash
#Dynaminc Mapping 根据类型和字段名
DELETE my_index
PUT my_index/_doc/1
{
"firstName": "Ruan",
"isVIP": "true"
}
GET my_index/_mapping
DELETE my_index
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"strings_as_boolean": {
"match_mapping_type": "string",
"match": "is*",
"mapping": {
"type": "boolean"
}
}
},
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
GET my_index/_mapping
DELETE my_index
#结合路径
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
GET my_index/_mapping
PUT my_index/_doc/1
{
"name": {
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
GET my_index/_search?q=full_name:John
DELETE my_index
```
## Mapping
在 Elasticsearch 中,**`Mapping`**(映射),用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、字段的权重、分词器等属性,就如同在关系型数据库中创建数据表时会设置字段的类型。
Mapping 会把 json 文档映射成 Lucene 所需要的扁平格式
一个 Mapping 属于一个索引的 Type
- 每个文档都属于一个 Type
- 一个 Type 有一个 Mapping 定义
- 7.0 开始,不需要在 Mapping 定义中指定 type 信息
### 映射分类
在 Elasticsearch 中,映射可分为静态映射和动态映射。
#### 静态映射
**静态映射**是在创建索引时手工指定索引映射。静态映射和 SQL 中在建表语句中指定字段属性类似。相比动态映射,通过静态映射可以添加更详细、更精准的配置信息。
如何定义一个 Mapping
```bash
PUT /books
{
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
...
}
}
```
#### 动态映射
**动态映射**是一种偷懒的方式,可直接创建索引并写入文档,文档中字段的类型是 Elasticsearch **自动识别**的,不需要在创建索引的时候设置字段的类型。在实际项目中,如果遇到的业务在导入数据之前不确定有哪些字段,也不清楚字段的类型是什么,使用动态映射非常合适。当 Elasticsearch 在文档中碰到一个以前没见过的字段时,它会利用动态映射来决定该字段的类型,并自动把该字段添加到映射中,根据字段的取值自动推测字段类型的规则见下表:
| JSON 格式的数据 | 自动推测的字段类型 |
| :-------------- | :--------------------------------------------------------------------------------- |
| null | 没有字段被添加 |
| true or false | boolean 类型 |
| 浮点类型数字 | float 类型 |
| 数字 | long 类型 |
| JSON 对象 | object 类型 |
| 数组 | 由数组中第一个非空值决定 |
| string | 有可能是 date 类型若开启日期检测、double 或 long 类型、text 类型、keyword 类型 |
下面举一个例子认识动态 mapping在 Elasticsearch 中创建一个新的索引并查看它的 mapping命令如下
```bash
PUT books
GET books/_mapping
```
此时 books 索引的 mapping 是空的,返回结果如下:
```json
{
"books": {
"mappings": {}
}
}
```
再往 books 索引中写入一条文档,命令如下:
```bash
PUT books/it/1
{
"id": 1,
"publish_date": "2019-11-10",
"name": "master Elasticsearch"
}
```
文档写入完成之后,再次查看 mapping返回结果如下
```json
{
"books": {
"mappings": {
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publish_date": {
"type": "date"
}
}
}
}
}
```
使用动态 mapping 要结合实际业务需求来综合考虑,如果将 Elasticsearch 当作主要的数据存储使用,并且希望出现未知字段时抛出异常来提醒你注意这一问题,那么开启动态 mapping 并不适用。在 mapping 中可以通过 `dynamic` 设置来控制是否自动新增字段,接受以下参数:
- **`true`**:默认值为 true自动添加字段。
- **`false`**:忽略新的字段。
- **`strict`**:严格模式,发现新的字段抛出异常。
### 基础类型
| 类型 | 关键字 |
| :--------- | :------------------------------------------------------------------ |
| 字符串类型 | string、text、keyword |
| 数字类型 | long、integer、short、byte、double、float、half_float、scaled_float |
| 日期类型 | date |
| 布尔类型 | boolean |
| 二进制类型 | binary |
| 范围类型 | range |
### 复杂类型
| 类型 | 关键字 |
| :------- | :----- |
| 数组类型 | array |
| 对象类型 | object |
| 嵌套类型 | nested |
### 特殊类型
| 类型 | 关键字 |
| :----------- | :---------- |
| 地理类型 | geo_point |
| 地理图形类型 | geo_shape |
| IP 类型 | ip |
| 范围类型 | completion |
| 令牌计数类型 | token_count |
| 附件类型 | attachment |
| 抽取类型 | percolator |
### Mapping 属性
Elasticsearch 的 mapping 中的字段属性非常多,具体如下表格:
| 属性名 | 描述 |
| :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **_`type`_** | 字段类型,常用的有 text、integer 等等。 |
| **_`index`_** | 当前字段是否被作为索引。可选值为 **_`true`_**,默认为 true。 |
| **_`store`_** | 是否存储指定字段,可选值为 **_`true`_** | **_`false`_**,设置 true 意味着需要开辟单独的存储空间为这个字段做存储,而且这个存储是独立于 **_`_source`_** 的存储的。 |
| **_`norms`_** | 是否使用归一化因子,可选值为 **_`true`_** | **_`false`_**不需要对某字段进行打分排序时可禁用它节省空间_type_ 为 _text_ 时,默认为 _true_;而 _type__keyword_ 时,默认为 _false_。 |
| **_`index_options`_** | 索引选项控制添加到倒排索引Inverted Index的信息这些信息用于搜索Search和高亮显示**_`docs`_**:只索引文档编号(Doc Number)**_`freqs`_**索引文档编号和词频率term frequency**_`positions`_**:索引文档编号,词频率和词位置(序号);**_`offsets`_**索引文档编号词频率词偏移量开始和结束位置和词位置序号。默认情况下被分析的字符串analyzed string字段使用 _positions_,其他字段默认使用 _docs_。此外,需要注意的是 _index_option_ 是 elasticsearch 特有的设置属性临近搜索和短语查询时_index_option_ 必须设置为 _offsets_,同时高亮也可使用 postings highlighter。 |
| **_`term_vector`_** | 索引选项控制词向量相关信息:**_`no`_**:默认值,表示不存储词向量相关信息;**_`yes`_**:只存储词向量信息;**_`with_positions`_**:存储词项和词项位置;**_`with_offsets`_**:存储词项和字符偏移位置;**_`with_positions_offsets`_**存储词项、词项位置、字符偏移位置。_term_vector_ 是 lucene 层面的索引设置。 |
| **_`similarity`_** | 指定文档相似度算法(也可以叫评分模型):**_`BM25`_**es 5 之后的默认设置。 |
| **_`copy_to`_** | 复制到自定义 \_all 字段,值是数组形式,即表明可以指定多个自定义的字段。 |
| **_`analyzer`_** | 指定索引和搜索时的分析器,如果同时指定 _search_analyzer_ 则搜索时会优先使用 _search_analyzer_。 |
| **_`search_analyzer`_** | 指定搜索时的分析器,搜索时的优先级最高。 |
| **_`null_value`_** | 用于需要对 Null 值实现搜索的场景,只有 Keyword 类型支持此配置。 |
## 分词
## 节点
### 节点简介
一个运行中的 Elasticsearch 实例称为一个**节点**。
Elasticsearch 实例本质上是一个 Java 进程。一台机器上可以运行多个 Elasticsearch 进程,但是生产环境建议一台机器上只运行一个 Elasticsearch 进程
每个节点都有名字,通过配置文件配置,或启动时通过 `-E node.name=node1` 指定。
每个节点在启动后,会分配一个 UID保存在 data 目录下。
### 节点类型
- **主节点master node**:每个节点都保存了集群的状态,只有 master 节点才能修改集群的状态信息(保证数据一致性)。**集群状态**,维护了以下信息:
- 所有的节点信息
- 所有的索引和其相关的 mapping 和 setting 信息
- 分片的路由信息
- **候选节点master eligible node**master eligible 节点可以参加选主流程。第一个启动的节点,会将自己选举为 mater 节点。
- 每个节点启动后,默认为 master eligible 节点,可以通过配置 `node.master: false` 禁止
- **数据节点data node**:负责保存分片数据。
- **协调节点coordinating node**:负责接收客户端的请求,将请求分发到合适的接地那,最终把结果汇集到一起。每个 Elasticsearch 节点默认都是协调节点coordinating node
- **冷/热节点warm/hot node**针对不同硬件配置的数据节点data node用来实现 Hot & Warm 架构,降低集群部署的成本。
- **机器学习节点machine learning node**:负责执行机器学习的 Job用来做异常检测。
### 节点配置
| 配置参数 | 默认值 | 说明 |
| ----------- | ------ | ------------------------------------- |
| node.master | true | 是否为主节点 |
| node.data | true | 是否为数据节点 |
| node.ingest | true | |
| node.ml | true | 是否为机器学习节点(需要开启 x-pack |
> **建议**
>
> 开发环境中一个节点可以承担多种角色。但是,在生产环境中,节点应该设置为单一角色。
## 集群
### 集群简介
拥有相同 `cluster.name` 配置的 Elasticsearch 节点组成一个**集群**。 `cluster.name` 默认名为 `elasticsearch`,可以通过配置文件修改,或启动时通过 `-E cluster.name=xxx` 指定。
当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
当一个节点被选举成为主节点时,它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量增加,它也不会成为瓶颈。 任何节点都可以成为主节点。
作为用户,我们可以将请求发送到集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。
### 集群健康
Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 _集群健康_ 它在 `status` 字段中展示为 `green``yellow` 或者 `red`
在一个不包含任何索引的空集群中,它将会有一个类似于如下所示的返回内容:
```js
{
"cluster_name" : "elasticsearch",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
```
`status` 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
- **`green`**:所有的主分片和副本分片都正常运行。
- **`yellow`**:所有的主分片都正常运行,但不是所有的副本分片都正常运行。
- **`red`**:有主分片没能正常运行。
## 分片
### 分片简介
索引实际上是指向一个或者多个**物理分片**的**逻辑命名空间** 。
一个分片是一个底层的工作单元 ,它仅保存了全部数据中的一部分。一个分片可以视为一个 Lucene 的实例,并且它本身就是一个完整的搜索引擎。 我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。
Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
### 主分片和副分片
分片分为主分片Primary Shard和副分片Replica Shard
主分片:用于解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内不同节点上。
- 索引内任意一个文档都归属于一个主分片。
- 主分片数在索引创建时指定,后序不允许修改,除非 Reindex
副分片Replica Shard用于解决数据高可用的问题。副分片是主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份并为搜索和返回文档等读操作提供服务。
- 副分片数可以动态调整
- 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)
对于生产环境中分片的设定,需要提前做好容量规划
分片数过小
- 无法水平扩展
- 单个分片的数量太大,导致数据重新分配耗时
分片数过大
- 影响搜索结果的相关性打分,影响统计结果的准确性
- 单节点上过多的分片,会导致资源浪费,同时也会影响性能
### 故障转移
当集群中只有一个节点运行时,意味着存在单点故障问题——没有冗余。
## 参考资料
- [Elasticsearch 官网](https://www.elastic.co/)
- [Elasticsearch 索引映射类型及 mapping 属性详解](https://www.knowledgedict.com/tutorial/elasticsearch-index-mapping.html)

View File

@ -2,11 +2,44 @@
Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。作为一个开箱即用的产品,在生产环境上线之后,我们其实不一定能确保其的性能和稳定性。如何根据实际情况提高服务的性能,其实有很多技巧。这章我们分享从实战经验中总结出来的 elasticsearch 性能优化,主要从硬件配置优化、索引优化设置、查询方面优化、数据结构优化、集群架构优化等方面讲解。
## 硬件配置优化
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 硬件配置优化](#1-硬件配置优化)
- [1.1. CPU 配置](#11-cpu-配置)
- [1.2. 内存配置](#12-内存配置)
- [1.3. 磁盘](#13-磁盘)
- [2. 索引优化设置](#2-索引优化设置)
- [2.1. 批量提交](#21-批量提交)
- [2.2. 增加 Refresh 时间间隔](#22-增加-refresh-时间间隔)
- [2.3. 修改 index_buffer_size 的设置](#23-修改-index_buffer_size-的设置)
- [2.4. 修改 translog 相关的设置](#24-修改-translog-相关的设置)
- [2.5. 注意 \_id 字段的使用](#25-注意-_id-字段的使用)
- [2.6. 注意 \_all 字段及 \_source 字段的使用](#26-注意-_all-字段及-_source-字段的使用)
- [2.7. 合理的配置使用 index 属性](#27-合理的配置使用-index-属性)
- [2.8. 减少副本数量](#28-减少副本数量)
- [3. 查询方面优化](#3-查询方面优化)
- [3.1. 路由优化](#31-路由优化)
- [3.2. Filter VS Query](#32-filter-vs-query)
- [3.3. 深度翻页](#33-深度翻页)
- [3.4. 脚本script合理使用](#34-脚本script合理使用)
- [4. 数据结构优化](#4-数据结构优化)
- [4.1. 尽量减少不需要的字段](#41-尽量减少不需要的字段)
- [4.2. Nested Object vs Parent/Child](#42-nested-object-vs-parentchild)
- [4.3. 选择静态映射,非必需时,禁止动态映射](#43-选择静态映射非必需时禁止动态映射)
- [5. 集群架构设计](#5-集群架构设计)
- [5.1. 主节点、数据节点和协调节点分离](#51-主节点数据节点和协调节点分离)
- [5.2. 关闭 data 节点服务器中的 http 功能](#52-关闭-data-节点服务器中的-http-功能)
- [5.3. 一台服务器上最好只部署一个 node](#53-一台服务器上最好只部署一个-node)
- [5.4. 集群分片设置](#54-集群分片设置)
- [6. 参考资料](#6-参考资料)
<!-- /TOC -->
## 1. 硬件配置优化
升级硬件设备配置一直都是提高服务能力最快速有效的手段在系统层面能够影响应用性能的一般包括三个因素CPU、内存和 IO可以从这三方面进行 ES 的性能优化工作。
### CPU 配置
### 1.1. CPU 配置
一般说来CPU 繁忙的原因有以下几个:
@ -16,7 +49,7 @@ Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中
大多数 Elasticsearch 部署往往对 CPU 要求不高。因此相对其它资源具体配置多少个CPU不是那么关键。你应该选择具有多个内核的现代处理器常见的集群使用 2 到 8 个核的机器。**如果你要在更快的 CPUs 和更多的核数之间选择,选择更多的核数更好**。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。
### 内存配置
### 1.2. 内存配置
如果有一种资源是最先被耗尽的,它可能是内存。排序和聚合都很耗内存,所以有足够的堆空间来应付它们是很重要的。即使堆空间是比较小的时候,也能为操作系统文件缓存提供额外的内存。因为 Lucene 使用的许多数据结构是基于磁盘的格式Elasticsearch 利用操作系统缓存能产生很大效果。
@ -44,7 +77,7 @@ Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中
保持线程池的现有设置,目前 ES 的线程池较 1.X 有了较多优化设置,保持现状即可;默认线程池大小等于 CPU 核心数。如果一定要改,按公式 ( ( CPU 核心数 \* 3 ) / 2 ) + 1 设置;不能超过 CPU 核心数的 2 倍;但是不建议修改默认配置,否则会对 CPU 造成硬伤。
### 磁盘
### 1.3. 磁盘
硬盘对所有的集群都很重要,对大量写入的集群更是加倍重要(例如那些存储日志数据的)。硬盘是服务器上最慢的子系统,这意味着那些写入量很大的集群很容易让硬盘饱和,使得它成为集群的瓶颈。
@ -64,11 +97,11 @@ Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中
**最后避免使用网络附加存储NAS**。人们常声称他们的 NAS 解决方案比本地驱动器更快更可靠。除却这些声称,我们从没看到 NAS 能配得上它的大肆宣传。NAS 常常很慢,显露出更大的延时和更宽的平均延时方差,而且它是单点故障的。
## 索引优化设置
## 2. 索引优化设置
索引优化主要是在 Elasticsearch 的插入层面优化Elasticsearch 本身索引速度其实还是蛮快的,具体数据,我们可以参考官方的 benchmark 数据。我们可以根据不同的需求,针对索引优化。
### 批量提交
### 2.1. 批量提交
当有大量数据提交的时候建议采用批量提交Bulk 操作);此外使用 bulk 请求时,每个请求不超过几十 M因为太大会导致内存使用过大。
@ -78,7 +111,7 @@ Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中
如果在提交过程中,遇到 EsRejectedExecutionException 异常的话,则说明集群的索引性能已经达到极限了。这种情况,要么提高服务器集群的资源,要么根据业务规则,减少数据收集速度,比如只收集 Warn、Error 级别以上的日志。
### 增加 Refresh 时间间隔
### 2.2. 增加 Refresh 时间间隔
为了提高索引性能Elasticsearch 在写入数据的时候,采用延迟写入的策略,即数据先写到内存中,当超过默认 1 秒index.refresh_interval会进行一次写入操作就是将内存中 segment 数据刷新到磁盘中,此时我们才能将数据搜索出来,所以这就是为什么 Elasticsearch 提供的是近实时搜索功能,而不是实时搜索功能。
@ -86,7 +119,7 @@ Elasticsearch 是当前流行的企业级搜索引擎,设计用于云计算中
> 在加载大量数据时候可以暂时不用 refresh 和 repliccasindex.refresh_interval 设置为-1index.number_of_replicas 设置为 0。
### 修改 index_buffer_size 的设置
### 2.3. 修改 index_buffer_size 的设置
索引缓冲的设置可以控制多少内存分配给索引进程。这是一个全局配置,会应用于一个节点上所有不同的分片上。
@ -97,7 +130,7 @@ indices.memory.min_index_buffer_size: 48mb
`indices.memory.index_buffer_size` 接受一个百分比或者一个表示字节大小的值。默认是 10%,意味着分配给节点的总内存的 10%用来做索引缓冲的大小。这个数值被分到不同的分片shards上。如果设置的是百分比还可以设置 `min_index_buffer_size` (默认 48mb`max_index_buffer_size`(默认没有上限)。
### 修改 translog 相关的设置
### 2.4. 修改 translog 相关的设置
一是控制数据从内存到硬盘的操作频率,以减少硬盘 IO。可将 sync_interval 的时间设置大一些。默认为 5s。
@ -111,29 +144,29 @@ index.translog.sync_interval: 5s
index.translog.flush_threshold_size: 512mb
```
### 注意 \_id 字段的使用
### 2.5. 注意 \_id 字段的使用
\_id 字段的使用,应尽可能避免自定义 \_id以避免针对 ID 的版本管理;建议使用 ES 的默认 ID 生成策略或使用数字类型 ID 做为主键。
### 注意 \_all 字段及 \_source 字段的使用
### 2.6. 注意 \_all 字段及 \_source 字段的使用
**\_**all 字段及 \_source 字段的使用,应该注意场景和需要,\_all 字段包含了所有的索引字段,方便做全文检索,如果无此需求,可以禁用;\_source 存储了原始的 document 内容,如果没有获取原始文档数据的需求,可通过设置 includes、excludes 属性来定义放入 \_source 的字段。
### 合理的配置使用 index 属性
### 2.7. 合理的配置使用 index 属性
合理的配置使用 index 属性analyzed 和 not_analyzed根据业务需求来控制字段是否分词或不分词。只有 groupby 需求的字段,配置时就设置成 not_analyzed以提高查询或聚类的效率。
### 减少副本数量
### 2.8. 减少副本数量
Elasticsearch 默认副本数量为 3 个,虽然这样会提高集群的可用性,增加搜索的并发数,但是同时也会影响写入索引的效率。
在索引过程中,需要把更新的文档发到副本节点上,等副本节点生效后在进行返回结束。使用 Elasticsearch 做业务搜索的时候,建议副本数目还是设置为 3 个,但是像内部 ELK 日志系统、分布式跟踪系统中,完全可以将副本数目设置为 1 个。
## 查询方面优化
## 3. 查询方面优化
Elasticsearch 作为业务搜索的近实时查询时,查询效率的优化显得尤为重要。
### 路由优化
### 3.1. 路由优化
当我们查询文档的时候Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?它其实是通过下面这个公式来计算出来的。
@ -156,7 +189,7 @@ routing 默认值是文档的 id也可以采用自定义值比如用户 ID
向上面自定义的用户查询,如果 routing 设置为 userid 的话,就可以直接查询出数据来,效率提升很多。
### Filter VS Query
### 3.2. Filter VS Query
尽可能使用过滤器上下文Filter替代查询上下文Query
@ -165,7 +198,7 @@ routing 默认值是文档的 id也可以采用自定义值比如用户 ID
Elasticsearch 针对 Filter 查询只需要回答「是」或者「否」,不需要像 Query 查询一样计算相关性分数,同时 Filter 结果可以缓存。
### 深度翻页
### 3.3. 深度翻页
在使用 Elasticsearch 过程中,应尽量避免大翻页的出现。
@ -175,15 +208,15 @@ Elasticsearch 针对 Filter 查询只需要回答「是」或者「否」,不
也可以结合实际业务特点,文档 id 大小如果和文档创建时间是一致有序的,可以以文档 id 作为分页的偏移量,并将其作为分页查询的一个条件。
### 脚本script合理使用
### 3.4. 脚本script合理使用
我们知道脚本使用主要有 3 种形式,内联动态编译方式、\_script 索引库中存储和文件脚本存储的形式;一般脚本的使用场景是粗排,尽量用第二种方式先将脚本存储在 \_script 索引库中,起到提前编译,然后通过引用脚本 id并结合 params 参数使用,即可以达到模型(逻辑)和数据进行了分离,同时又便于脚本模块的扩展与维护。具体 ES 脚本的深入内容请参考 [Elasticsearch 脚本模块的详解](https://www.knowledgedict.com/tutorial/elasticsearch-script.html)。
## 数据结构优化
## 4. 数据结构优化
基于 Elasticsearch 的使用场景,文档数据结构尽量和使用场景进行结合,去掉没用及不合理的数据。
### 尽量减少不需要的字段
### 4.1. 尽量减少不需要的字段
如果 Elasticsearch 用于业务搜索服务,一些不需要用于搜索的字段最好不存到 ES 中,这样即节省空间,同时在相同的数据量下,也能提高搜索性能。
@ -197,7 +230,7 @@ index.mapping.total_fields.limit: 1000
index.mapping.depth.limit: 20
```
### Nested Object vs Parent/Child
### 4.2. Nested Object vs Parent/Child
尽量避免使用 nested 或 parent/child 的字段能不用就不用nested query 慢parent/child query 更慢,比 nested query 慢上百倍;因此能在 mapping 设计阶段搞定的(大宽表设计或采用比较 smart 的数据结构),就不要用父子关系的 mapping。
@ -213,17 +246,17 @@ index.mapping.nested_fields.limit: 50
| 缺点 | 更新父文档或子文档时需要更新整个文档 | 为了维护 join 关系,需要占用部分内存,读取性能较差 |
| 场景 | 子文档偶尔更新,查询频繁 | 子文档更新频繁 |
### 选择静态映射,非必需时,禁止动态映射
### 4.3. 选择静态映射,非必需时,禁止动态映射
尽量避免使用动态映射,这样有可能会导致集群崩溃,此外,动态映射有可能会带来不可控制的数据类型,进而有可能导致在查询端出现相关异常,影响业务。
此外Elasticsearch 作为搜索引擎时,主要承载 query 的匹配和排序的功能,那数据的存储类型基于这两种功能的用途分为两类,一是需要匹配的字段,用来建立倒排索引对 query 匹配用,另一类字段是用做粗排用到的特征字段,如 ctr、点击数、评论数等等。
## 集群架构设计
## 5. 集群架构设计
合理的部署 Elasticsearch 有助于提高服务的整体可用性。
### 主节点、数据节点和协调节点分离
### 5.1. 主节点、数据节点和协调节点分离
Elasticsearch 集群在架构拓朴时,采用主节点、数据节点和负载均衡节点分离的架构,在 5.x 版本以后又可将数据节点再细分为“Hot-Warm”的架构模式。
@ -273,23 +306,23 @@ node.attr.box_type: warm
- node.master:true 和 node.data:false该 node 服务器只作为一个主节点,但不存储任何索引数据,该 node 服务器将使用自身空闲的资源,来协调各种创建索引请求或者查询请求,并将这些请求合理分发到相关的 node 服务器上。
- node.master:false 和 node.data:false该 node 服务器即不会被选作主节点,也不会存储任何索引数据。该服务器主要用于查询负载均衡。在查询的时候,通常会涉及到从多个 node 服务器上查询数据,并将请求分发到多个指定的 node 服务器,并对各个 node 服务器返回的结果进行一个汇总处理,最终返回给客户端。
### 关闭 data 节点服务器中的 http 功能
### 5.2. 关闭 data 节点服务器中的 http 功能
针对 Elasticsearch 集群中的所有数据节点,不用开启 http 服务。将其中的配置参数这样设置,`http.enabled:false`,同时也不要安装 head, bigdesk, marvel 等监控插件,这样保证 data 节点服务器只需处理创建/更新/删除/查询索引数据等操作。
http 功能可以在非数据节点服务器上开启,上述相关的监控插件也安装到这些服务器上,用于监控 Elasticsearch 集群状态等数据信息。这样做一来出于数据安全考虑,二来出于服务性能考虑。
### 一台服务器上最好只部署一个 node
### 5.3. 一台服务器上最好只部署一个 node
一台物理服务器上可以启动多个 node 服务器节点(通过设置不同的启动 port但一台服务器上的 CPU、内存、硬盘等资源毕竟有限从服务器性能考虑不建议一台服务器上启动多个 node 节点。
### 集群分片设置
### 5.4. 集群分片设置
ES 一旦创建好索引后,就无法调整分片的设置,而在 ES 中,一个分片实际上对应一个 lucene 索引,而 lucene 索引的读写会占用很多的系统资源,因此,分片数不能设置过大;所以,在创建索引时,合理配置分片数是非常重要的。一般来说,我们遵循一些原则:
1. 控制每个分片占用的硬盘容量不超过 ES 的最大 JVM 的堆空间设置(一般设置不超过 32 G参考上面的 JVM 内存设置原则),因此,如果索引的总容量在 500 G 左右,那分片大小在 16 个左右即可;当然,最好同时考虑原则 2。
2. 考虑一下 node 数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了 1 个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以,**一般都设置分片数不超过节点数的 3 倍**。
## 参考资料
## 6. 参考资料
- [Elasticsearch 教程](https://www.knowledgedict.com/tutorial/elasticsearch-intro.html)

View File

@ -2,13 +2,26 @@
在 Elasticsearch 中,默认排序是**按照相关性的评分(\_score**进行降序排序,也可以按照**字段的值排序**、**多级排序**、**多值字段排序、基于 geo地理位置排序以及自定义脚本排序**,除此之外,对于相关性的评分也可以用 rescore 二次、三次打分它可以限定重新打分的窗口大小window size并针对作用范围内的文档修改其得分从而达到精细化控制结果相关性的目的。
## 默认相关性排序
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 默认相关性排序](#1-默认相关性排序)
- [1.1. TF-IDF 模型](#11-tf-idf-模型)
- [1.2. BM25 模型](#12-bm25-模型)
- [2. 字段的值排序](#2-字段的值排序)
- [3. 多字段排序](#3-多字段排序)
- [4. 多值字段的排序](#4-多值字段的排序)
- [5. 地理位置上的距离排序](#5-地理位置上的距离排序)
- [6. 参考资料](#6-参考资料)
<!-- /TOC -->
## 1. 默认相关性排序
在 Elasticsearch 中,默认情况下,文档是按照相关性得分倒序排列的,其对应的相关性得分字段用 `_score` 来表示,它是浮点数类型,`_score` 评分越高,相关性越高。评分模型的选择可以通过 `similarity` 参数在映射中指定。
相似度算法可以按字段指定,只需在映射中为不同字段选定即可,如果要修改已有字段的相似度算法,只能通过为数据重新建立索引来达到目的。关于更多 es 相似度算法可以参考 [深入理解 es 相似度算法(相关性得分计算)](https://www.knowledgedict.com/tutorial/elasticsearch-similarity.html)。
### TF-IDF 模型
### 1.1. TF-IDF 模型
Elasticsearch 在 5.4 版本以前text 类型的字段,默认采用基于 tf-idf 的向量空间模型。
@ -40,15 +53,15 @@ Elasticsearch 在 5.4 版本以前text 类型的字段,默认采用基于 t
一旦词频 TF 和逆文档频率 IDF 计算完成,就可以使用 TF-IDF 公式来计算文档的得分。
### BM25 模型
### 1.2. BM25 模型
Elasticsearch 在 5.4 版本之后,针对 text 类型的字段,默认采用的是 BM25 评分模型,而不是基于 tf-idf 的向量空间模型,评分模型的选择可以通过 `similarity` 参数在映射中指定。
## 字段的值排序
## 2. 字段的值排序
在 Elasticsearch 中按照字段的值排序,可以利用 `sort` 参数实现。
```
```bash
GET books/_search
{
"sort": {
@ -61,7 +74,7 @@ GET books/_search
返回结果如下:
```
```json
{
"took": 132,
"timed_out": false,
@ -95,13 +108,13 @@ GET books/_search
}
```
从如上返回结果,可以看出,`max_score` 和 `_score` 字段都返回 `null`,返回字段多出 `sort` 字段,包含排序字段的分值。计算 \_score 的花销巨大,如果不根据相关性排序,记录 \_score 是没有意义的。如果无论如何都要计算 \_score可以将 `track_scores` 参数设置为 `true`
从如上返回结果,可以看出,`max_score` 和 `_score` 字段都返回 `null`,返回字段多出 `sort` 字段,包含排序字段的分值。计算 \_`score` 的花销巨大,如果不根据相关性排序,记录 \_`score` 是没有意义的。如果无论如何都要计算 \_`score`,可以将 `track_scores` 参数设置为 `true`
## 多字段排序
## 3. 多字段排序
如果我们想要结合使用 price、date 和 \_score 进行查询,并且匹配的结果首先按照价格排序,然后按照日期排序,最后按照相关性排序,具体示例如下:
```
```bash
GET books/_search
{
"query": {
@ -135,13 +148,13 @@ GET books/_search
多级排序并不一定包含 `_score`。你可以根据一些不同的字段进行排序,如地理距离或是脚本计算的特定值。
## 多值字段的排序
## 4. 多值字段的排序
一种情形是字段有多个值的排序,需要记住这些值并没有固有的顺序;一个多值的字段仅仅是多个值的包装,这时应该选择哪个进行排序呢?
对于数字或日期,你可以将多值字段减为单值,这可以通过使用 `min`、`max`、`avg` 或是 `sum` 排序模式。例如你可以按照每个 date 字段中的最早日期进行排序,通过以下方法:
```
```json
"sort": {
"dates": {
"order": "asc",
@ -150,11 +163,11 @@ GET books/_search
}
```
## 地理位置上的距离排序
## 5. 地理位置上的距离排序
es 的地理位置排序使用 **`_geo_distance`** 来进行距离排序,如下示例:
```
```json
{
"sort" : [
{
@ -183,6 +196,6 @@ _\_geo_distance_ 的选项具体如下:
- **_`ignore_unmapped`_**:未映射字段时,是否忽略处理,可选项有 **_`true`_****_`false`_**;默认为 _false_,表示如果未映射字段,查询将引发异常;若设置 _true_,将忽略未映射的字段,并且不匹配此查询的任何文档。
- **_`validation_method`_**:指定检验经纬度数据的方式,可选项有 **_`IGNORE_MALFORMED`_**、**_`COERCE`_** 和 **_`STRICT`_**_IGNORE_MALFORMED_ 表示可接受纬度或经度无效的地理点即忽略数据_COERCE_ 表示另外尝试并推断正确的地理坐标_STRICT_ 为默认值,表示遇到不正确的地理坐标直接抛出异常。
## 参考资料
## 6. 参考资料
- [Elasticsearch 教程](https://www.knowledgedict.com/tutorial/elasticsearch-intro.html)

View File

@ -14,7 +14,7 @@ Elasticsearch 查询语句采用基于 RESTful 风格的接口封装成 JSON 格
- [1.7. combined_fields query](#17-combined_fields-query)
- [1.8. common_terms query](#18-common_terms-query)
- [1.9. query_string query](#19-query_string-query)
- [1.10. simple_query_string](#110-simple_query_string)
- [1.10. simple_query_string query](#110-simple_query_string-query)
- [1.11. 全文查询完整示例](#111-全文查询完整示例)
- [2. 词项查询](#2-词项查询)
- [2.1. exists query](#21-exists-query)
@ -453,7 +453,7 @@ GET /_search
}
```
### 1.10. simple_query_string
### 1.10. simple_query_string query
[**`simple_query_string query`**](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html) 是一种适合直接暴露给用户,并且具有非常完善的查询语法的查询语句,接受 Lucene 查询语法,解析过程中发生错误不会抛出异常。

View File

@ -1,22 +1,475 @@
# Elasticsearch 简介
Elasticsearch 是一款基于 Lunece 的开源分布式搜索分析引擎。
Elasticsearch 是一个基于 Lucene 的搜索和数据分析工具它提供了一个分布式服务。Elasticsearch 是遵从 Apache 开源条款的一款开源产品,是当前主流的企业级搜索引擎。
为什么使用 Elasticsearch
它用于全文搜索、结构化搜索、分析以及将这三者混合使用:
- 查询性能好
- 分布式设计,易于水平扩展
- 支持多种语言的集成
- 社区活跃,业界广泛使用
- 维基百科使用 Elasticsearch 提供全文搜索并高亮关键字,以及**输入实时搜索(search-as-you-type)**和**搜索纠错(did-you-mean)**等搜索建议功能。
- 英国卫报使用 Elasticsearch 结合用户日志和社交网络数据提供给他们的编辑以实时的反馈,以便及时了解公众对新发表的文章的回应。
- StackOverflow 结合全文搜索与地理位置查询,以及**more-like-this**功能来找到相关的问题和答案。
- Github 使用 Elasticsearch 检索 1300 亿行的代码。
## Elastic Stack 生态
<!-- TOC depthFrom:2 depthTo:3 -->
### Logstash
- [1. Elasticsearch 特点](#1-elasticsearch-特点)
- [2. Elasticsearch 发展历史](#2-elasticsearch-发展历史)
- [3. Elasticsearch 概念](#3-elasticsearch-概念)
- [3.1. 近实时NRT](#31-近实时nrt)
- [3.2. 索引Index](#32-索引index)
- [3.3. ~~类型Type~~](#33-类型type)
- [3.4. 文档Document](#34-文档document)
- [3.5. 节点Node](#35-节点node)
- [3.6. 集群Cluster](#36-集群cluster)
- [3.7. 分片Shards](#37-分片shards)
- [3.8. 副本Replicas](#38-副本replicas)
- [4. 参考资料](#4-参考资料)
### Kibana
<!-- /TOC -->
### Beats
## 1. Elasticsearch 特点
## 参考资料
- 分布式的实时文件存储,每个字段都被索引并可被搜索;
- 分布式的实时分析搜索引擎;
- 可弹性扩展到上百台服务器规模,处理 PB 级结构化或非结构化数据;
- 开箱即用(安装即可使用),它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。只需很少的学习既可在生产环境中使用。
## 2. Elasticsearch 发展历史
- 2010 年 2 月 8 日Elasticsearch 第一个公开版本发布。
- 2010 年 5 月 14 日,发布第一个具有里程碑意义的初始版本 **0.7.0** ,具有如下特征:
- Zen Discovery 自动发现模块;
- 支持 Groovy Client
- 简单的插件管理机制;
- 更好地支持 icu 分词器;
- 更多的管理 api。
- 2013 年初GitHub 抛弃了 Solr采取 ElasticSearch 来做其 PB 级的搜索。
- 2014 年 2 月 14 日,发布 **1.0.0** 版本,增加如下重要特性:
- 支持 Snapshot/Restore API 备份恢复 API
- 支持聚合分析 Aggregations
- 支持 cat api
- 支持断路器;
- 引入 Doc values。
- 2015 年 10 月 28 日,发布 **2.0.0** 版本,有如下重要特性:
- 增加了 Pipleline Aggregations
- query/filter 查询合并,都合并到 query 中,根据不同的上下文执行不同的查询;
- 压缩存储可配置;
- Rivers 模块被移除;
- Multicast 组播发现被移除,成为一个插件,生产环境必须配置单播地址。
- 2016 年 10 月 26 日,发布 **5.0.0** 版本,有如下重大特性变化:
- Lucene 6.x 的支持,磁盘空间少一半;索引时间少一半;查询性能提升 25%;支持 IPV6
- Internal Engine 级别移除了用于避免同一文档并发更新的竞争锁,带来 15%-20% 的性能提升;
- Shrink API它可将分片数进行收缩成它的因数如之前你是 15 个分片,你可以收缩成 5 个或者 3 个又或者 1 个,那么我们就可以想象成这样一种场景,在写入压力非常大的收集阶段,设置足够多的索引,充分利用 shard 的并行写能力,索引写完之后收缩成更少的 shard提高查询性能
- 提供了第一个 Java 原生的 REST 客户端 SDK
- IngestNode之前如果需要对数据进行加工都是在索引之前进行处理比如 logstash 可以对日志进行结构化和转换,现在直接在 es 就可以处理了;
- 提供了 Painless 脚本,代替 Groovy 脚本;
- 移除 site plugins就是说 head、bigdesk 都不能直接装 es 里面了,不过可以部署独立站点(反正都是静态文件)或开发 kibana 插件;
- 新增 Sliced Scroll 类型,现在 Scroll 接口可以并发来进行数据遍历了。每个 Scroll 请求,可以分成多个 Slice 请求,可以理解为切片,各 Slice 独立并行,利用 Scroll 重建或者遍历要快很多倍;
- 新增了 Profile API
- 新增了 Rollover API
- 新增 Reindex
- 引入新的字段类型 Text/Keyword 来替换 String
- 限制索引请求大小,避免大量并发请求压垮 ES
- 限制单个请求的 shards 数量,默认 1000 个。
- 2017 年 8 月 31 日,发布 **6.0.0** 版本,具有如下重要特性:
- 稀疏性 Doc Values 的支持;
- Index Sorting即索引阶段的排序
- 顺序号的支持,每个 es 的操作都有一个顺序编号(类似增量设计);
- 无缝滚动升级;
- 从 6.0 开始不支持一个 index 里面存在多个 type
- Index-template inheritance索引版本的继承目前索引模板是所有匹配的都会合并这样会造成索引模板有一些冲突问题 6.0 将会只匹配一个,索引创建时也会进行验证;
- Load aware shard routing 基于负载的请求路由,目前的搜索请求是全节点轮询,那么性能最慢的节点往往会造成整体的延迟增加,新的实现方式将基于队列的耗费时间自动调节队列长度,负载高的节点的队列长度将减少,让其他节点分摊更多的压力,搜索和索引都将基于这种机制;
- 已经关闭的索引将也支持 replica 的自动处理,确保数据可靠。
- 2019 年 4 月 10 日,发布 **7.0.0** 版本,具有如下重要特性:
- 集群连接变化TransportClient 被废弃es7 的 java 代码,只能使用 restclient对于 java 编程,建议采用 High-level-rest-client 的方式操作 ES 集群;
- ES 程序包默认打包 jdk7.x 版本的程序包大小变成 300MB+,对比 6.x包大了 200MB+,这正是 JDK 的大小;
- 采用基于 Lucene 9.0
- 正式废除单个索引下多 Type 的支持es6 时,官方就提到了 es7 会删除 type并且 es6 时,已经规定每一个 index 只能有一个 type。在 es7 中,使用默认的 \_doc 作为 type官方说在 8.x 版本会彻底移除 type。api 请求方式也发送变化,如获得某索引的某 ID 的文档GET index/\_doc/id 其中 index 和 id 为具体的值;
- 引入了真正的内存断路器,它可以更精准地检测出无法处理的请求,并防止它们使单个节点不稳定;
- Zen2 是 Elasticsearch 的全新集群协调层,提高了可靠性、性能和用户体验,变得更快、更安全,并更易于使用。
## 3. Elasticsearch 概念
下列有一些概念是 Elasticsearch 的核心。从一开始就理解这些概念将极大地帮助简化学习 Elasticsearch 的过程。
### 3.1. 近实时NRT
Elasticsearch 是一个近乎实时的搜索平台。这意味着**从索引文档到可搜索文档的时间有一点延迟**(通常是一秒)。
### 3.2. 索引Index
索引在不同语境,有着不同的含义
- 索引(名词):一个 **索引** 类似于传统关系数据库中的一个 **数据库** ,是一个存储关系型文档的容器。 索引 (_index_) 的复数词为 indices 或 indexes 。索引实际上是指向一个或者多个**物理分片**的**逻辑命名空间** 。
- 索引(动词):索引一个文档 就是存储一个文档到一个 _索引_ (名词)中以便被检索和查询。这非常类似于 SQL 语句中的 `INSERT` 关键词,除了文档已存在时,新文档会替换旧文档情况之外。
- 倒排索引:关系型数据库通过增加一个索引比如一个 B 树索引到指定的列上以便提升数据检索速度。Elasticsearch 和 Lucene 使用了一个叫做 **倒排索引** 的结构来达到相同的目的。
索引的 Mapping 和 Setting
- **`Mapping`** 定义文档字段的类型
- **`Setting`** 定义不同的数据分布
示例:
```json
{
"settings": { ... any settings ... },
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
...
}
}
```
#### 倒排索引
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220108215559.PNG)
#### index template
**`index template`**(索引模板)帮助用户设定 Mapping 和 Setting并按照一定的规则自动匹配到新创建的索引之上。
- 模板仅在一个索引被创建时,才会产生作用。修改模板不会影响已创建的索引。
- 你可以设定多个索引模板,这些设置会被 merge 在一起。
- 你可以指定 order 的数值,控制 merge 的过程。
当新建一个索引时
- 应用 ES 默认的 Mapping 和 Setting
- 应用 order 数值低的 index template 中的设定
- 应用 order 数值高的 index template 中的设定,之前的设定会被覆盖
- 应用创建索引是,用户所指定的 Mapping 和 Setting并覆盖之前模板中的设定。
示例:创建默认索引模板
```bash
PUT _template/template_default
{
"index_patterns": ["*"],
"order": 0,
"version": 1,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
PUT /_template/template_test
{
"index_patterns": ["test*"],
"order": 1,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 2
},
"mappings": {
"date_detection": false,
"numeric_detection": true
}
}
# 查看索引模板
GET /_template/template_default
GET /_template/temp*
#写入新的数据index以test开头
PUT testtemplate/_doc/1
{
"someNumber": "1",
"someDate": "2019/01/01"
}
GET testtemplate/_mapping
GET testtemplate/_settings
PUT testmy
{
"settings":{
"number_of_replicas":5
}
}
PUT testmy/_doc/1
{
"key": "value"
}
GET testmy/_settings
DELETE testmy
DELETE /_template/template_default
DELETE /_template/template_test
```
#### dynamic template
- 根据 ES 识别的数据类型,结合字段名称,来动态设定字段类型
- 所有的字符串类型都设定成 Keyword或者关闭 keyword 字段。
- is 开头的字段都设置成 boolean
- long\_ 开头的都设置成 long 类型
- dynamic template 是定义在某个索引的 Mapping 中
- template 有一个名称
- 匹配规则是一个数组
- 为匹配到字段设置 Mapping
示例:
```bash
#Dynaminc Mapping 根据类型和字段名
DELETE my_index
PUT my_index/_doc/1
{
"firstName": "Ruan",
"isVIP": "true"
}
GET my_index/_mapping
DELETE my_index
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"strings_as_boolean": {
"match_mapping_type": "string",
"match": "is*",
"mapping": {
"type": "boolean"
}
}
},
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
GET my_index/_mapping
DELETE my_index
#结合路径
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
GET my_index/_mapping
PUT my_index/_doc/1
{
"name": {
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
GET my_index/_search?q=full_name:John
DELETE my_index
```
### 3.3. ~~类型Type~~
~~type 是一个逻辑意义上的分类或者叫分区,允许在同一索引中建立多个 type。本质是相当于一个过滤条件高版本将会废弃 type 概念。~~
> ~~**6.0.0 版本及之后,废弃 type**~~
### 3.4. 文档Document
Elasticsearch 是面向文档的,**文档是所有可搜索数据的最小单位**。
Elasticsearch 使用 [_JSON_](http://en.wikipedia.org/wiki/Json) 作为文档的序列化格式。
在索引/类型中,可以根据需要存储任意数量的文档。
每个文档都有一个 **Unique ID**
- 用户可以自己指定
- 或通过 Elasticsearch 自动生成
#### 文档的元数据
一个文档不仅仅包含它的数据 ,也包含**元数据** —— 有关文档的信息。
- `_index`:文档在哪存放
- `_type`:文档表示的对象类别
- `_id`:文档唯一标识
- `_source`:文档的原始 Json 数据
- `_all`:整合所有字段内容到该字段,已被废除
- `_version`:文档的版本信息
- `_score`:相关性打分
示例:
```json
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": ["sports", "music"]
}
}
```
### 3.5. 节点Node
#### 节点简介
一个运行中的 Elasticsearch 实例称为一个**节点**。
Elasticsearch 实例本质上是一个 Java 进程。一台机器上可以运行多个 Elasticsearch 进程,但是生产环境建议一台机器上只运行一个 Elasticsearch 进程
每个节点都有名字,通过配置文件配置,或启动时通过 `-E node.name=node1` 指定。
每个节点在启动后,会分配一个 UID保存在 `data` 目录下。
#### 节点类型
- **主节点master node**:每个节点都保存了集群的状态,只有 master 节点才能修改集群的状态信息(保证数据一致性)。**集群状态**,维护了以下信息:
- 所有的节点信息
- 所有的索引和其相关的 mapping 和 setting 信息
- 分片的路由信息
- **候选节点master eligible node**master eligible 节点可以参加选主流程。第一个启动的节点,会将自己选举为 mater 节点。
- 每个节点启动后,默认为 master eligible 节点,可以通过配置 `node.master: false` 禁止
- **数据节点data node**:负责保存分片数据。
- **协调节点coordinating node**:负责接收客户端的请求,将请求分发到合适的接地那,最终把结果汇集到一起。每个 Elasticsearch 节点默认都是协调节点coordinating node
- **冷/热节点warm/hot node**针对不同硬件配置的数据节点data node用来实现 Hot & Warm 架构,降低集群部署的成本。
- **机器学习节点machine learning node**:负责执行机器学习的 Job用来做异常检测。
#### 节点配置
| 配置参数 | 默认值 | 说明 |
| ----------- | ------ | ------------------------------------- |
| node.master | true | 是否为主节点 |
| node.data | true | 是否为数据节点 |
| node.ingest | true | |
| node.ml | true | 是否为机器学习节点(需要开启 x-pack |
> **建议**
>
> 开发环境中一个节点可以承担多种角色。但是,在生产环境中,节点应该设置为单一角色。
### 3.6. 集群Cluster
#### 集群简介
拥有相同 `cluster.name` 配置的 Elasticsearch 节点组成一个**集群**。 `cluster.name` 默认名为 `elasticsearch`,可以通过配置文件修改,或启动时通过 `-E cluster.name=xxx` 指定。
当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
当一个节点被选举成为主节点时,它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量增加,它也不会成为瓶颈。 任何节点都可以成为主节点。
作为用户,我们可以将请求发送到集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。
#### 集群健康
Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 _集群健康_ 它在 `status` 字段中展示为 `green``yellow` 或者 `red`
在一个不包含任何索引的空集群中,它将会有一个类似于如下所示的返回内容:
```js
{
"cluster_name" : "elasticsearch",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
```
`status` 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
- **`green`**:所有的主分片和副本分片都正常运行。
- **`yellow`**:所有的主分片都正常运行,但不是所有的副本分片都正常运行。
- **`red`**:有主分片没能正常运行。
### 3.7. 分片Shards
#### 分片简介
索引实际上是指向一个或者多个**物理分片**的**逻辑命名空间** 。
一个分片是一个底层的工作单元 ,它仅保存了全部数据中的一部分。一个分片可以视为一个 Lucene 的实例,并且它本身就是一个完整的搜索引擎。 我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。
Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
#### 主分片和副分片
分片分为主分片Primary Shard和副分片Replica Shard
主分片:用于解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内不同节点上。
- 索引内任意一个文档都归属于一个主分片。
- 主分片数在索引创建时指定,后序不允许修改,除非 Reindex
副分片Replica Shard用于解决数据高可用的问题。副分片是主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份并为搜索和返回文档等读操作提供服务。
- 副分片数可以动态调整
- 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)
对于生产环境中分片的设定,需要提前做好容量规划
分片数过小
- 无法水平扩展
- 单个分片的数量太大,导致数据重新分配耗时
分片数过大
- 影响搜索结果的相关性打分,影响统计结果的准确性
- 单节点上过多的分片,会导致资源浪费,同时也会影响性能
### 3.8. 副本Replicas
副本主要是针对主分片Shards的复制Elasticsearch 中主分片可以拥有 0 个或多个的副本。
副本分片的主要目的就是为了故障转移。
分片副本很重要,主要有两个原因:
- 它在分片或节点发生故障时提供高可用性。因此,副本分片永远不会在与其复制的主分片相同的节点;
- 副本分片也可以接受搜索的请求,可以并行搜索,从而提高系统的吞吐量。
> 每个 Elasticsearch 分片都是 Lucene 索引。单个 Lucene 索引中可以包含最大数量的文档。截止 LUCENE-5843限制是 2,147,483,519= `Integer.MAX_VALUE` - 128文档。您可以使用\_cat/shardsAPI 监控分片大小。
## 4. 参考资料
- [Elasticsearch 官网](https://www.elastic.co/)
- [Elasticsearch 简介](https://www.knowledgedict.com/tutorial/elasticsearch-intro.html)

View File

@ -0,0 +1,480 @@
# Elasticsearch 索引管理
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 索引管理操作](#1-索引管理操作)
- [1.1. 索引删除](#11-索引删除)
- [1.2. 索引别名](#12-索引别名)
- [2. Settings 详解](#2-settings-详解)
- [2.1. 固定属性](#21-固定属性)
- [2.2. 索引静态配置](#22-索引静态配置)
- [2.3. 索引动态配置](#23-索引动态配置)
- [3. Mapping 详解](#3-mapping-详解)
- [3.1. 映射分类](#31-映射分类)
- [3.2. 基础类型](#32-基础类型)
- [3.3. 复杂类型](#33-复杂类型)
- [3.4. 特殊类型](#34-特殊类型)
- [3.5. Mapping 属性](#35-mapping-属性)
- [4. 索引查询](#4-索引查询)
- [4.1. 多个 index、多个 type 查询](#41-多个index多个type查询)
- [4.2. URI 搜索](#42-uri搜索)
- [4.3. 查询流程](#43-查询流程)
- [5. 参考资料](#5-参考资料)
<!-- /TOC -->
## 1. 索引管理操作
Elasticsearch 索引管理主要包括如何进行索引的创建、索引的删除、副本的更新、索引读写权限、索引别名的配置等等内容。
### 1.1. 索引删除
ES 索引删除操作向 ES 集群的 http 接口发送指定索引的 delete http 请求即可,可以通过 curl 命令,具体如下:
```bash
curl -X DELETE http://{es_host}:{es_http_port}/{index}
```
如果删除成功,它会返回如下信息,具体示例如下:
```bash
curl -X DELETE http://10.10.10.66:9200/my_index?pretty
```
为了返回的信息便于读取,增加了 pretty 参数:
```bash
{
"acknowledged" : true
}
```
### 1.2. 索引别名
ES 的索引别名就是给一个索引或者多个索引起的另一个名字,典型的应用场景是针对索引使用的平滑切换。
首先,创建索引 my_index然后将别名 my_alias 指向它,示例如下:
```bash
PUT /my_index
PUT /my_index/_alias/my_alias
```
也可以通过如下形式:
```bash
POST /_aliases
{
"actions": [
{ "add": { "index": "my_index", "alias": "my_alias" }}
]
}
```
也可以在一次请求中增加别名和移除别名混合使用:
```bash
POST /_aliases
{
"actions": [
{ "remove": { "index": "my_index", "alias": "my_alias" }}
{ "add": { "index": "my_index_v2", "alias": "my_alias" }}
]
}
```
> 需要注意的是,如果别名与索引是一对一的,使用别名索引文档或者查询文档是可以的,但是如果别名和索引是一对多的,使用别名会发生错误,因为 ES 不知道把文档写入哪个索引中去或者从哪个索引中读取文档。
ES 索引别名有个典型的应用场景是平滑切换,更多细节可以查看 [ElasticsearchES索引零停机无需重启无缝平滑切换的方法](https://www.knowledgedict.com/tutorial/elasticsearch-index-smooth-shift.html)。
## 2. Settings 详解
Elasticsearch 索引的配置项主要分为**静态配置属性**和**动态配置属性**,静态配置属性是索引创建后不能修改,而动态配置属性则可以随时修改。
ES 索引设置的 api 为 **_`_settings`_**,完整的示例如下:
```bash
PUT /my_index
{
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "1",
"refresh_interval": "60s",
"analysis": {
"filter": {
"tsconvert": {
"type": "stconvert",
"convert_type": "t2s",
"delimiter": ","
},
"synonym": {
"type": "synonym",
"synonyms_path": "analysis/synonyms.txt"
}
},
"analyzer": {
"ik_max_word_synonym": {
"filter": [
"synonym",
"tsconvert",
"standard",
"lowercase",
"stop"
],
"tokenizer": "ik_max_word"
},
"ik_smart_synonym": {
"filter": [
"synonym",
"standard",
"lowercase",
"stop"
],
"tokenizer": "ik_smart"
}
},
"mapping": {
"coerce": "false",
"ignore_malformed": "false"
},
"indexing": {
"slowlog": {
"threshold": {
"index": {
"warn": "2s",
"info": "1s"
}
}
}
},
"provided_name": "hospital_202101070533",
"query": {
"default_field": "timestamp",
"parse": {
"allow_unmapped_fields": "false"
}
},
"requests": {
"cache": {
"enable": "true"
}
},
"search": {
"slowlog": {
"threshold": {
"fetch": {
"warn": "1s",
"info": "200ms"
},
"query": {
"warn": "1s",
"info": "500ms"
}
}
}
}
}
}
}
```
### 2.1. 固定属性
- **_`index.creation_date`_**:顾名思义索引的创建时间戳。
- **_`index.uuid`_**:索引的 uuid 信息。
- **_`index.version.created`_**:索引的版本号。
### 2.2. 索引静态配置
- **_`index.number_of_shards`_**:索引的主分片数,默认值是 **_`5`_**。这个配置在索引创建后不能修改;在 es 层面,可以通过 **_`es.index.max_number_of_shards`_** 属性设置索引最大的分片数,默认为 **_`1024`_**
- **_`index.codec`_**:数据存储的压缩算法,默认值为 **_`LZ4`_**,可选择值还有 **_`best_compression`_**,它比 LZ4 可以获得更好的压缩比(即占据较小的磁盘空间,但存储性能比 LZ4 低)。
- **_`index.routing_partition_size`_**:路由分区数,如果设置了该参数,其路由算法为:`( hash(_routing) + hash(_id) % index.routing_parttion_size ) % number_of_shards`。如果该值不设置,则路由算法为 `hash(_routing) % number_of_shardings``_routing` 默认值为 `_id`
静态配置里有重要的部分是配置分析器config analyzers
- **`index.analysis`**
:分析器最外层的配置项,内部主要分为 char_filter、tokenizer、filter 和 analyzer。
- **_`char_filter`_**:定义新的字符过滤器件。
- **_`tokenizer`_**:定义新的分词器。
- **_`filter`_**:定义新的 token filter如同义词 filter。
- **_`analyzer`_**:配置新的分析器,一般是 char_filter、tokenizer 和一些 token filter 的组合。
### 2.3. 索引动态配置
- **_`index.number_of_replicas`_**:索引主分片的副本数,默认值是 **_`1`_**,该值必须大于等于 0这个配置可以随时修改。
- **_`index.refresh_interval`_**:执行新索引数据的刷新操作频率,该操作使对索引的最新更改对搜索可见,默认为 **_`1s`_**。也可以设置为 **_`-1`_** 以禁用刷新。更详细信息参考 [Elasticsearch 动态修改 refresh_interval 刷新间隔设置](https://www.knowledgedict.com/tutorial/elasticsearch-refresh_interval-settings.html)。
## 3. Mapping 详解
在 Elasticsearch 中,**`Mapping`**(映射),用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、字段的权重、分词器等属性,就如同在关系型数据库中创建数据表时会设置字段的类型。
Mapping 会把 json 文档映射成 Lucene 所需要的扁平格式
一个 Mapping 属于一个索引的 Type
- 每个文档都属于一个 Type
- 一个 Type 有一个 Mapping 定义
- 7.0 开始,不需要在 Mapping 定义中指定 type 信息
### 3.1. 映射分类
在 Elasticsearch 中,映射可分为静态映射和动态映射。在关系型数据库中写入数据之前首先要建表,在建表语句中声明字段的属性,在 Elasticsearch 中则不必如此Elasticsearch 最重要的功能之一就是让你尽可能快地开始探索数据,文档写入 Elasticsearch 中,它会根据字段的类型自动识别,这种机制称为**动态映射**,而**静态映射**则是写入数据之前对字段的属性进行手工设置。
#### 静态映射
**静态映射**是在创建索引时手工指定索引映射。静态映射和 SQL 中在建表语句中指定字段属性类似。相比动态映射,通过静态映射可以添加更详细、更精准的配置信息。
如何定义一个 Mapping
```bash
PUT /books
{
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
...
}
}
```
#### 动态映射
**动态映射**是一种偷懒的方式,可直接创建索引并写入文档,文档中字段的类型是 Elasticsearch **自动识别**的,不需要在创建索引的时候设置字段的类型。在实际项目中,如果遇到的业务在导入数据之前不确定有哪些字段,也不清楚字段的类型是什么,使用动态映射非常合适。当 Elasticsearch 在文档中碰到一个以前没见过的字段时,它会利用动态映射来决定该字段的类型,并自动把该字段添加到映射中,根据字段的取值自动推测字段类型的规则见下表:
| JSON 格式的数据 | 自动推测的字段类型 |
| :-------------- | :--------------------------------------------------------------------------------- |
| null | 没有字段被添加 |
| true or false | boolean 类型 |
| 浮点类型数字 | float 类型 |
| 数字 | long 类型 |
| JSON 对象 | object 类型 |
| 数组 | 由数组中第一个非空值决定 |
| string | 有可能是 date 类型若开启日期检测、double 或 long 类型、text 类型、keyword 类型 |
下面举一个例子认识动态 mapping在 Elasticsearch 中创建一个新的索引并查看它的 mapping命令如下
```bash
PUT books
GET books/_mapping
```
此时 books 索引的 mapping 是空的,返回结果如下:
```json
{
"books": {
"mappings": {}
}
}
```
再往 books 索引中写入一条文档,命令如下:
```bash
PUT books/it/1
{
"id": 1,
"publish_date": "2019-11-10",
"name": "master Elasticsearch"
}
```
文档写入完成之后,再次查看 mapping返回结果如下
```json
{
"books": {
"mappings": {
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publish_date": {
"type": "date"
}
}
}
}
}
```
使用动态 mapping 要结合实际业务需求来综合考虑,如果将 Elasticsearch 当作主要的数据存储使用,并且希望出现未知字段时抛出异常来提醒你注意这一问题,那么开启动态 mapping 并不适用。在 mapping 中可以通过 `dynamic` 设置来控制是否自动新增字段,接受以下参数:
- **`true`**:默认值为 true自动添加字段。
- **`false`**:忽略新的字段。
- **`strict`**:严格模式,发现新的字段抛出异常。
### 3.2. 基础类型
| 类型 | 关键字 |
| :--------- | :------------------------------------------------------------------ |
| 字符串类型 | string、text、keyword |
| 数字类型 | long、integer、short、byte、double、float、half_float、scaled_float |
| 日期类型 | date |
| 布尔类型 | boolean |
| 二进制类型 | binary |
| 范围类型 | range |
### 3.3. 复杂类型
| 类型 | 关键字 |
| :------- | :----- |
| 数组类型 | array |
| 对象类型 | object |
| 嵌套类型 | nested |
### 3.4. 特殊类型
| 类型 | 关键字 |
| :----------- | :---------- |
| 地理类型 | geo_point |
| 地理图形类型 | geo_shape |
| IP 类型 | ip |
| 范围类型 | completion |
| 令牌计数类型 | token_count |
| 附件类型 | attachment |
| 抽取类型 | percolator |
### 3.5. Mapping 属性
Elasticsearch 的 mapping 中的字段属性非常多,具体如下表格:
| 属性名 | 描述 |
| :- | :- | |
| **_`type`_** | 字段类型,常用的有 text、integer 等等。 |
| **_`index`_** | 当前字段是否被作为索引。可选值为 **_`true`_**,默认为 true。 |
| **_`store`_** | 是否存储指定字段,可选值为 **_`true`_** | **_`false`_**,设置 true 意味着需要开辟单独的存储空间为这个字段做存储,而且这个存储是独立于 **_`_source`_** 的存储的。 |
| **_`norms`_** | 是否使用归一化因子,可选值为 **_`true`_** | **_`false`_**不需要对某字段进行打分排序时可禁用它节省空间_type_ 为 _text_ 时,默认为 _true_;而 _type__keyword_ 时,默认为 _false_。 |
| **_`index_options`_** | 索引选项控制添加到倒排索引Inverted Index的信息这些信息用于搜索Search和高亮显示**_`docs`_**:只索引文档编号(Doc Number)**_`freqs`_**索引文档编号和词频率term frequency**_`positions`_**:索引文档编号,词频率和词位置(序号);**_`offsets`_**索引文档编号词频率词偏移量开始和结束位置和词位置序号。默认情况下被分析的字符串analyzed string字段使用 _positions_,其他字段默认使用 _docs_。此外,需要注意的是 _index_option_ 是 elasticsearch 特有的设置属性临近搜索和短语查询时_index_option_ 必须设置为 _offsets_,同时高亮也可使用 postings highlighter。 |
| **_`term_vector`_** | 索引选项控制词向量相关信息:**_`no`_**:默认值,表示不存储词向量相关信息;**_`yes`_**:只存储词向量信息;**_`with_positions`_**:存储词项和词项位置;**_`with_offsets`_**:存储词项和字符偏移位置;**_`with_positions_offsets`_**存储词项、词项位置、字符偏移位置。_term_vector_ 是 lucene 层面的索引设置。 |
| **_`similarity`_** | 指定文档相似度算法(也可以叫评分模型):**_`BM25`_**ES 5 之后的默认设置。 |
| **_`copy_to`_** | 复制到自定义 \_all 字段,值是数组形式,即表明可以指定多个自定义的字段。 |
| **_`analyzer`_** | 指定索引和搜索时的分析器,如果同时指定 _search_analyzer_ 则搜索时会优先使用 _search_analyzer_。 |
| **_`search_analyzer`_** | 指定搜索时的分析器,搜索时的优先级最高。 |
| **_`null_value`_** | 用于需要对 Null 值实现搜索的场景,只有 Keyword 类型支持此配置。 |
## 4. 索引查询
### 4.1. 多个 index、多个 type 查询
Elasticsearch 的搜索 api 支持**一个索引index的多个类型type查询**以及**多个索引index**的查询。
例如,我们可以搜索 twitter 索引下面所有匹配条件的所有类型中文档,如下:
```bash
GET /twitter/_search?q=user:shay
```
我们也可以搜索一个索引下面指定多个 type 下匹配条件的文档,如下:
```bash
GET /twitter/tweet,user/_search?q=user:banon
```
我们也可以搜索多个索引下匹配条件的文档,如下:
```bash
GET /twitter,elasticsearch/_search?q=tag:wow
```
此外我们也可以搜索所有索引下匹配条件的文档,用\_all 表示所有索引,如下:
```bash
GET /_all/_search?q=tag:wow
```
甚至我们可以搜索所有索引及所有 type 下匹配条件的文档,如下:
```bash
GET /_search?q=tag:wow
```
### 4.2. URI 搜索
Elasticsearch 支持用 uri 搜索,可用 get 请求里面拼接相关的参数,并用 curl 相关的命令就可以进行测试。
如下有一个示例:
```bash
GET twitter/_search?q=user:kimchy
```
如下是上一个请求的相应实体:
```json
{
"timed_out": false,
"took": 62,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.3862944,
"hits": [
{
"_index": "twitter",
"_type": "_doc",
"_id": "0",
"_score": 1.3862944,
"_source": {
"user": "kimchy",
"date": "2009-11-15T14:12:12",
"message": "trying out Elasticsearch",
"likes": 0
}
}
]
}
}
```
URI 中允许的参数:
| 名称 | 描述 |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| q | 查询字符串,映射到 query_string 查询 |
| df | 在查询中未定义字段前缀时使用的默认字段 |
| analyzer | 查询字符串时指定的分词器 |
| analyze_wildcard | 是否允许通配符和前缀查询,默认设置为 false |
| batched_reduce_size | 应在协调节点上一次减少的分片结果数。如果请求中潜在的分片数量很大,则应将此值用作保护机制,以减少每个搜索请求的内存开销 |
| default_operator | 默认使用的匹配运算符,可以是*AND*或者*OR*,默认是*OR* |
| lenient | 如果设置为 true将会忽略由于格式化引起的问题如向数据字段提供文本默认为 false |
| explain | 对于每个 hit包含了具体如何计算得分的解释 |
| \_source | 请求文档内容的参数,默认 true设置 false 的话,不返回\_source 字段,可以使用**\_source_include**和**\_source_exclude**参数分别指定返回字段和不返回的字段 |
| stored_fields | 指定每个匹配返回的文档中的存储字段,多个用逗号分隔。不指定任何值将导致没有字段返回 |
| sort | 排序方式,可以是*fieldName*、*fieldName:asc*或者*fieldName:desc*的形式。fieldName 可以是文档中的实际字段,也可以是诸如\_score 字段,其表示基于分数的排序。此外可以指定多个 sort 参数(顺序很重要) |
| track_scores | 当排序时,若设置 true返回每个命中文档的分数 |
| track_total_hits | 是否返回匹配条件命中的总文档数,默认为 true |
| timeout | 设置搜索的超时时间,默认无超时时间 |
| terminate_after | 在达到查询终止条件之前,指定每个分片收集的最大文档数。如果设置,则在响应中多了一个 terminated_early 的布尔字段,以指示查询执行是否实际上已终止。默认为 no terminate_after |
| from | 从第几条(索引以 0 开始)结果开始返回,默认为 0 |
| size | 返回命中的文档数,默认为 10 |
| search_type | 搜索的方式,可以是*dfs_query_then_fetch*或*query_then_fetch*。默认为*query_then_fetch* |
| allow_partial_search_results | 是否可以返回部分结果。如设置为 false表示如果请求产生部分结果则设置为返回整体故障默认为 true表示允许请求在超时或部分失败的情况下获得部分结果 |
### 4.3. 查询流程
在 Elasticsearch 中,查询是一个比较复杂的执行模式,因为我们不知道那些 document 会被匹配到,任何一个 shard 上都有可能,所以一个 search 请求必须查询一个索引或多个索引里面的所有 shard 才能完整的查询到我们想要的结果。
找到所有匹配的结果是查询的第一步,来自多个 shard 上的数据集在分页返回到客户端之前会被合并到一个排序后的 list 列表,由于需要经过一步取 top N 的操作,所以 search 需要进过两个阶段才能完成,分别是 query 和 fetch。
## 5. 参考资料
- [Elasticsearch 官网](https://www.elastic.co/)
- [Elasticsearch 索引映射类型及 mapping 属性详解](https://www.knowledgedict.com/tutorial/elasticsearch-index-mapping.html)

View File

@ -1,8 +1,31 @@
# Elasticsearch 聚合
Elasticsearch 是一个分布式的全文搜索引擎,索引和搜索是 Elasticsearch 的基本功能。事实上Elasticsearch 的聚合Aggregations功能也十分强大允许在数据上做复杂的分析统计。Elasticsearch 提供的聚合分析功能主要有**指标聚合metrics aggregations**、**桶聚合bucket aggregations**、**管道聚合pipeline aggregations**和**矩阵聚合matrix aggregations**四大类,管道聚合和矩阵聚合官方说明是在试验阶段,后期会完全更改或者移除,这里不再对管道聚合和矩阵聚合进行讲解。
Elasticsearch 是一个分布式的全文搜索引擎,索引和搜索是 Elasticsearch 的基本功能。事实上Elasticsearch 的聚合Aggregations功能也十分强大允许在数据上做复杂的分析统计。Elasticsearch 提供的聚合分析功能主要有**指标聚合(metrics aggregations)**、**桶聚合(bucket aggregations)**、**管道聚合(pipeline aggregations)** 和 **矩阵聚合(matrix aggregations)** 四大类,管道聚合和矩阵聚合官方说明是在试验阶段,后期会完全更改或者移除,这里不再对管道聚合和矩阵聚合进行讲解。
## 聚合的具体结构
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 聚合的具体结构](#1-聚合的具体结构)
- [2. 指标聚合](#2-指标聚合)
- [2.1. Max Aggregation](#21-max-aggregation)
- [2.2. Min Aggregation](#22-min-aggregation)
- [2.3. Avg Aggregation](#23-avg-aggregation)
- [2.4. Sum Aggregation](#24-sum-aggregation)
- [2.5. Value Count Aggregation](#25-value-count-aggregation)
- [2.6. Cardinality Aggregation](#26-cardinality-aggregation)
- [2.7. Stats Aggregation](#27-stats-aggregation)
- [2.8. Extended Stats Aggregation](#28-extended-stats-aggregation)
- [2.9. Percentiles Aggregation](#29-percentiles-aggregation)
- [2.10. Percentiles Ranks Aggregation](#210-percentiles-ranks-aggregation)
- [3. 桶聚合](#3-桶聚合)
- [3.1. Terms Aggregation](#31-terms-aggregation)
- [3.2. Filter Aggregation](#32-filter-aggregation)
- [3.3. Filters Aggregation](#33-filters-aggregation)
- [3.4. Range Aggregation](#34-range-aggregation)
- [4. 参考资料](#4-参考资料)
<!-- /TOC -->
## 1. 聚合的具体结构
所有的聚合,无论它们是什么类型,都遵从以下的规则。
@ -35,9 +58,7 @@ Elasticsearch 是一个分布式的全文搜索引擎,索引和搜索是 Elast
>
> 此外脚本也可以被人可能利用进行恶意代码攻击尽量使用沙盒sandbox内的脚本语言。
### 示例
查询所有球员的平均年龄是多少,并对球员的平均薪水加 188也可以理解为每名球员加 188 后的平均薪水)。
示例:查询所有球员的平均年龄是多少,并对球员的平均薪水加 188也可以理解为每名球员加 188 后的平均薪水)。
```bash
POST /player/_search?size=0
@ -59,13 +80,13 @@ POST /player/_search?size=0
}
```
## 指标聚合
## 2. 指标聚合
指标聚合(又称度量聚合)主要从不同文档的分组中提取统计数据,或者,从来自其他聚合的文档桶来提取统计数据。
这些统计数据通常来自数值型字段,如最小或者平均价格。用户可以单独获取每项统计数据,或者也可以使用 stats 聚合来同时获取它们。更高级的统计数据,如平方和或者是标准差,可以通过 extended stats 聚合来获取。
### Max Aggregation
### 2.1. Max Aggregation
Max Aggregation 用于最大值统计。例如,统计 sales 索引中价格最高的是哪本书,并且计算出对应的价格的 2 倍值,查询语句如下:
@ -108,7 +129,7 @@ GET /sales/_search?size=0
}
```
### Min Aggregation
### 2.2. Min Aggregation
Min Aggregation 用于最小值统计。例如,统计 sales 索引中价格最低的是哪本书,查询语句如下:
@ -138,7 +159,7 @@ GET /sales/_search?size=0
}
```
### Avg Aggregation
### 2.3. Avg Aggregation
Avg Aggregation 用于计算平均值。例如,统计 exams 索引中考试的平均分数,如未存在分数,默认为 60 分,查询语句如下:
@ -173,7 +194,7 @@ GET /exams/_search?size=0
除了常规的平均值聚合计算外elasticsearch 还提供了加权平均值的聚合计算,详情参见 [Elasticsearch 指标聚合之 Weighted Avg Aggregation](https://www.knowledgedict.com/tutorial/elasticsearch-aggregations-metrics-weighted-avg-aggregation.html)。
### Sum Aggregation
### 2.4. Sum Aggregation
Sum Aggregation 用于计算总和。例如,统计 sales 索引中 type 字段中匹配 hat 的价格总和,查询语句如下:
@ -208,7 +229,7 @@ GET /exams/_search?size=0
}
```
### Value Count Aggregation
### 2.5. Value Count Aggregation
Value Count Aggregation 可按字段统计文档数量。例如,统计 books 索引中包含 author 字段的文档数量,查询语句如下:
@ -236,9 +257,9 @@ GET /books/_search?size=0
}
```
### Cardinality Aggregation
### 2.6. Cardinality Aggregation
Cardinality Aggregation 用于基数统计,其作用是先执行类似 SQL 中的 distinct 操作,去掉集合中的重复项,然后统计重后的集合长度。例如,在 books 索引中对 language 字段进行 cardinality 操作可以统计出编程语言的种类数,查询语句如下:
Cardinality Aggregation 用于基数统计,其作用是先执行类似 SQL 中的 distinct 操作,去掉集合中的重复项,然后统计重后的集合长度。例如,在 books 索引中对 language 字段进行 cardinality 操作可以统计出编程语言的种类数,查询语句如下:
```
GET /books/_search?size=0
@ -272,7 +293,7 @@ GET /books/_search?size=0
}
```
### Stats Aggregation
### 2.7. Stats Aggregation
Stats Aggregation 用于基本统计,会一次返回 count、max、min、avg 和 sum 这 5 个指标。例如,在 exams 索引中对 grade 字段进行分数相关的基本统计,查询语句如下:
@ -304,7 +325,7 @@ GET /exams/_search?size=0
}
```
### Extended Stats Aggregation
### 2.8. Extended Stats Aggregation
Extended Stats Aggregation 用于高级统计和基本统计功能类似但是会比基本统计多出以下几个统计结果sum_of_squares平方和、variance方差、std_deviation标准差、std_deviation_bounds平均值加/减两个标准差的区间)。在 exams 索引中对 grade 字段进行分数相关的高级统计,查询语句如下:
@ -343,7 +364,7 @@ GET /exams/_search?size=0
}
```
### Percentiles Aggregation
### 2.9. Percentiles Aggregation
Percentiles Aggregation 用于百分位统计。百分位数是一个统计学术语,如果将一组数据从大到小排序,并计算相应的累计百分位,某一百分位所对应数据的值就称为这一百分位的百分位数。默认情况下,累计百分位为 [ 1, 5, 25, 50, 75, 95, 99 ]。以下例子给出了在 latency 索引中对 load_time 字段进行加载时间的百分位统计,查询语句如下:
@ -401,7 +422,7 @@ GET latency/_search
}
```
### Percentiles Ranks Aggregation
### 2.10. Percentiles Ranks Aggregation
Percentiles Ranks Aggregation 与 Percentiles Aggregation 统计恰恰相反,就是想看当前数值处在什么范围内(百分位), 假如你查一下当前值 500 和 600 所处的百分位,发现是 90.01 和 100那么说明有 90.01 % 的数值都在 500 以内100 % 的数值在 600 以内。
@ -478,7 +499,7 @@ GET latency/_search
}
```
## 桶聚合
## 3. 桶聚合
bucket 可以理解为一个桶,它会遍历文档中的内容,凡是符合某一要求的就放入一个桶中,分桶相当于 SQL 中的 group by。从另外一个角度可以将指标聚合看成单桶聚合即把所有文档放到一个桶中而桶聚合是多桶型聚合它根据相应的条件进行分组。
@ -496,7 +517,7 @@ bucket 可以理解为一个桶,它会遍历文档中的内容,凡是符合
| 空值聚合Missing Aggregation | 空值聚合,可以把文档集中所有缺失字段的文档分到一个桶中。 |
| 地理点范围聚合Geo Distance Aggregation | 用于对地理点geo point做范围统计。 |
### Terms Aggregation
### 3.1. Terms Aggregation
Terms Aggregation 用于词项的分组聚合。最为经典的用例是获取 X 中最频繁top frequent的项目其中 X 是文档中的某个字段,如用户的名称、标签或分类。由于 terms 聚集统计的是每个词条,而不是整个字段值,因此通常需要在一个非分析型的字段上运行这种聚集。原因是, 你期望“big data”作为词组统计而不是“big”单独统计一次“data”再单独统计一次。
@ -586,7 +607,7 @@ Terms Aggregation 用于词项的分组聚合。最为经典的用例是获取 X
默认情况下返回按文档计数从高到低的前 10 个分组,可以通过 size 参数指定返回的分组数。
### Filter Aggregation
### 3.2. Filter Aggregation
Filter Aggregation 是过滤器聚合,可以把符合过滤器中的条件的文档分到一个桶中,即是单分组聚合。
@ -607,7 +628,7 @@ Filter Aggregation 是过滤器聚合,可以把符合过滤器中的条件的
}
```
### Filters Aggregation
### 3.3. Filters Aggregation
Filters Aggregation 是多过滤器聚合,可以把符合多个过滤条件的文档分到不同的桶中,即每个分组关联一个过滤条件,并收集所有满足自身过滤条件的文档。
@ -647,7 +668,7 @@ Filters Aggregation 是多过滤器聚合,可以把符合多个过滤条件的
}
```
### Range Aggregation
### 3.4. Range Aggregation
Range Aggregation 范围聚合是一个基于多组值来源的聚合,可以让用户定义一系列范围,每个范围代表一个分组。在聚合执行的过程中,从每个文档提取出来的值都会检查每个分组的范围,并且使相关的文档落入分组中。注意,范围聚合的每个范围内包含 from 值但是排除 to 值。
@ -718,6 +739,6 @@ Range Aggregation 范围聚合是一个基于多组值来源的聚合,可以
}
```
## 参考资料
## 4. 参考资料
- [Elasticsearch 教程](https://www.knowledgedict.com/tutorial/elasticsearch-intro.html)

View File

@ -2,15 +2,27 @@
> [Elasticsearch](https://github.com/elastic/elasticsearch) 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
## 部署
<!-- TOC depthFrom:2 depthTo:3 -->
### 安装步骤
- [1. Elasticsearch 安装](#1-elasticsearch-安装)
- [2. Elasticsearch 集群规划](#2-elasticsearch-集群规划)
- [3. Elasticsearch 配置](#3-elasticsearch-配置)
- [4. Elasticsearch FAQ](#4-elasticsearch-faq)
- [4.1. elasticsearch 不允许以 root 权限来运行](#41-elasticsearch-不允许以-root-权限来运行)
- [4.2. vm.max_map_count 不低于 262144](#42-vmmax_map_count-不低于-262144)
- [4.3. nofile 不低于 65536](#43-nofile-不低于-65536)
- [4.4. nproc 不低于 2048](#44-nproc-不低于-2048)
- [5. 参考资料](#5-参考资料)
> [Elasticsearch 官方开源版本安装说明](https://www.elastic.co/cn/downloads/elasticsearch-oss)
<!-- /TOC -->
## 1. Elasticsearch 安装
> [Elasticsearch 官方下载安装说明](https://www.elastic.co/cn/downloads/elasticsearch)
1下载解压
访问 [官方下载地址](https://www.elastic.co/cn/downloads/elasticsearch-oss) ,选择需要的版本,下载解压到本地。
访问 [官方下载地址](https://www.elastic.co/cn/downloads/elasticsearch) ,选择需要的版本,下载解压到本地。
2运行
@ -20,7 +32,7 @@
执行 `curl http://localhost:9200/` 测试服务是否启动
### 集群规划
## 2. Elasticsearch 集群规划
ElasticSearch 集群需要根据业务实际情况去合理规划。
@ -37,7 +49,7 @@ ElasticSearch 集群需要根据业务实际情况去合理规划。
- 我们 es 集群的日增量数据大概是 2000 万条,每天日增量数据大概是 500MB每月增量数据大概是 6 亿15G。目前系统已经运行了几个月现在 es 集群里数据总量大概是 100G 左右。
- 目前线上有 5 个索引(这个结合你们自己业务来,看看自己有哪些数据可以放 es 的),每个索引的数据量大概是 20G所以这个数据量之内我们每个索引分配的是 8 个 shard比默认的 5 个 shard 多了 3 个 shard。
## ES 配置
## 3. Elasticsearch 配置
ES 的默认配置文件为 `config/elasticsearch.yml`
@ -111,9 +123,9 @@ discovery.zen.ping.unicast.hosts: ['host1', 'host2:port', 'host3[portX-portY]']
#设置集群中master节点的初始列表可以通过这些节点来自动发现新加入集群的节点。
```
## FAQ
## 4. Elasticsearch FAQ
### elasticsearch 不允许以 root 权限来运行
### 4.1. elasticsearch 不允许以 root 权限来运行
**问题:**在 Linux 环境中elasticsearch 不允许以 root 权限来运行。
@ -136,7 +148,7 @@ chown -R elk:elk /opt # 假设你的 elasticsearch 安装在 opt 目录下
su elk
```
### vm.max_map_count 不低于 262144
### 4.2. vm.max_map_count 不低于 262144
**问题:**`vm.max_map_count` 表示虚拟内存大小它是一个内核参数。elasticsearch 默认要求 `vm.max_map_count` 不低于 262144。
@ -165,7 +177,7 @@ sysctl -p
>
> 这种情况下,你只能选择直接修改宿主机上的参数了。
### nofile 不低于 65536
### 4.3. nofile 不低于 65536
**问题:** `nofile` 表示进程允许打开的最大文件数。elasticsearch 进程要求可以打开的最大文件数不低于 65536。
@ -182,7 +194,7 @@ echo "* soft nofile 65536" > /etc/security/limits.conf
echo "* hard nofile 131072" > /etc/security/limits.conf
```
### nproc 不低于 2048
### 4.4. nproc 不低于 2048
**问题:** `nproc` 表示最大线程数。elasticsearch 要求最大线程数不低于 2048。
@ -199,10 +211,8 @@ echo "* soft nproc 2048" > /etc/security/limits.conf
echo "* hard nproc 4096" > /etc/security/limits.conf
```
## 参考资料
## 5. 参考资料
- [Elasticsearch 官网](https://www.elastic.co/cn/products/elasticsearch)
- [Elasticsearch Github](https://github.com/elastic/elasticsearch)
- [Elasticsearch 官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html)
- [Elasticsearch 官方下载安装说明](https://www.elastic.co/cn/downloads/elasticsearch)
- [Install Elasticsearch with RPM](https://www.elastic.co/guide/en/elasticsearch/reference/current/rpm.html#rpm)
- [Elasticsearch 使用积累](http://siye1982.github.io/2015/09/17/es-optimize/)

View File

@ -0,0 +1,123 @@
# Elasticsearch 高亮搜索及显示
Elasticsearch 的高亮highlight可以让您从搜索结果中的一个或多个字段中获取突出显示的摘要以便向用户显示查询匹配的位置。当您请求突出显示即高亮响应结果的 highlight 字段中包括高亮的字段和高亮的片段。Elasticsearch 默认会用 `<em></em>` 标签标记关键字。
<!-- TOC depthFrom:2 depthTo:3 -->
- [1. 高亮参数](#1-高亮参数)
- [2. 自定义高亮片段](#2-自定义高亮片段)
- [3. 多字段高亮](#3-多字段高亮)
- [4. 高亮性能分析](#4-高亮性能分析)
<!-- /TOC -->
## 1. 高亮参数
ES 提供了如下高亮参数:
| 参数 | 说明 |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `boundary_chars` | 包含每个边界字符的字符串。默认为,! ?\ \ n。 |
| `boundary_max_scan` | 扫描边界字符的距离。默认为 20。 |
| `boundary_scanner` | 指定如何分割突出显示的片段,支持 chars、sentence、word 三种方式。 |
| `boundary_scanner_locale` | 用来设置搜索和确定单词边界的本地化设置此参数使用语言标记的形式“en-US”, “fr-FR”, “ja-JP” |
| `encoder` | 表示代码段应该是 HTML 编码的:默认(无编码)还是 HTML (HTML-转义代码段文本,然后插入高亮标记) |
| `fields` | 指定检索高亮显示的字段。可以使用通配符来指定字段。例如,可以指定 comment*\*来获取以 comment*开头的所有文本和关键字字段的高亮显示。 |
| `force_source` | 根据源高亮显示。默认值为 false。 |
| `fragmenter` | 指定文本应如何在突出显示片段中拆分:支持参数 simple 或者 span。 |
| `fragment_offset` | 控制要开始突出显示的空白。仅在使用 fvh highlighter 时有效。 |
| `fragment_size` | 字符中突出显示的片段的大小。默认为 100。 |
| `highlight_query` | 突出显示搜索查询之外的其他查询的匹配项。这在使用重打分查询时特别有用,因为默认情况下高亮显示不会考虑这些问题。 |
| `matched_fields` | 组合多个匹配结果以突出显示单个字段,对于使用不同方式分析同一字符串的多字段。所有的 matched_fields 必须将 term_vector 设置为 with_positions_offsets但是只有将匹配项组合到的字段才会被加载因此只有将 store 设置为 yes 才能使该字段受益。只适用于 fvh highlighter。 |
| `no_match_size` | 如果没有要突出显示的匹配片段,则希望从字段开头返回的文本量。默认为 0(不返回任何内容)。 |
| `number_of_fragments` | 返回的片段的最大数量。如果片段的数量设置为 0则不会返回任何片段。相反突出显示并返回整个字段内容。当需要突出显示短文本(如标题或地址),但不需要分段时,使用此配置非常方便。如果 number_of_fragments 为 0则忽略 fragment_size。默认为 5。 |
| `order` | 设置为 score 时,按分数对突出显示的片段进行排序。默认情况下,片段将按照它们在字段中出现的顺序输出(order:none)。将此选项设置为 score 将首先输出最相关的片段。每个高亮应用自己的逻辑来计算相关性得分。 |
| `phrase_limit` | 控制文档中所考虑的匹配短语的数量。防止 fvh highlighter 分析太多的短语和消耗太多的内存。提高限制会增加查询时间并消耗更多内存。默认为 256。 |
| `pre_tags` | 与 post_tags 一起使用,定义用于突出显示文本的 HTML 标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。 |
| `post_tags` | 与 pre_tags 一起使用,定义用于突出显示文本的 HTML 标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。 |
| `require_field_match` | 默认情况下,只突出显示包含查询匹配的字段。将 require_field_match 设置为 false 以突出显示所有字段。默认值为 true。 |
| `tags_schema` | 设置为使用内置标记模式的样式。 |
| `type` | 使用的高亮模式,可选项为**_`unified`_**、**_`plain`_**或**_`fvh`_**。默认为 _`unified`_。 |
## 2. 自定义高亮片段
如果我们想使用自定义标签,在高亮属性中给需要高亮的字段加上 `pre_tags``post_tags` 即可。例如,搜索 title 字段中包含关键词 javascript 的书籍并使用自定义 HTML 标签高亮关键词,查询语句如下:
```bash
GET /books/_search
{
"query": {
"match": { "title": "javascript" }
},
"highlight": {
"fields": {
"title": {
"pre_tags": ["<strong>"],
"post_tags": ["</strong>"]
}
}
}
}
```
## 3. 多字段高亮
关于搜索高亮,还需要掌握如何设置多字段搜索高亮。比如,搜索 title 字段的时候,我们期望 description 字段中的关键字也可以高亮,这时候就需要把 `require_field_match` 属性的取值设置为 `fasle`。`require_field_match` 的默认值为 `true`,只会高亮匹配的字段。多字段高亮的查询语句如下:
```bash
GET /books/_search
{
"query": {
"match": { "title": "javascript" }
},
"highlight": {
"require_field_match": false,
"fields": {
"title": {},
"description": {}
}
}
}
```
## 4. 高亮性能分析
Elasticsearch 提供了三种高亮器,分别是**默认的 highlighter 高亮器**、**postings-highlighter 高亮器**和 **fast-vector-highlighter 高亮器**
默认的 **highlighter** 是最基本的高亮器。highlighter 高亮器实现高亮功能需要对 `_source` 中保存的原始文档进行二次分析,其速度在三种高亮器里最慢,优点是不需要额外的存储空间。
**postings-highlighter** 高亮器实现高亮功能不需要二次分析,但是需要在字段的映射中设置 `index_options` 参数的取值为 `offsets`,即保存关键词的偏移量,速度快于默认的 highlighter 高亮器。例如,配置 comment 字段使用 postings-highlighter 高亮器,映射如下:
```bash
PUT /example
{
"mappings": {
"doc": {
"properties": {
"comment": {
"type": "text",
"index_options": "offsets"
}
}
}
}
}
```
**fast-vector-highlighter** 高亮器实现高亮功能速度最快,但是需要在字段的映射中设置 `term_vector` 参数的取值为 `with_positions_offsets`,即保存关键词的位置和偏移信息,占用的存储空间最大,是典型的空间换时间的做法。例如,配置 comment 字段使用 fast-vector-highlighter 高亮器,映射如下:
```bash
PUT /example
{
"mappings": {
"doc": {
"properties": {
"comment": {
"type": "text",
"term_vector": "with_positions_offsets"
}
}
}
}
}
```

View File

@ -1,23 +1,32 @@
# Elasticsearch 教程
> Elasticsearch 是一个基于 Lucene 的搜索和数据分析工具它提供了一个分布式服务。Elasticsearch 是遵从 Apache 开源条款的一款开源产品,是当前主流的企业级搜索引擎。
## 📖 内容
### Elasticsearch
### [Elasticsearch 面试总结](elasticsearch-interview.md) 💯
> [Elasticsearch](https://www.elastic.co/products/elasticsearch) 是一个基于 [Lucene](http://lucene.apache.org/core/documentation.html) 构建的开源分布式RESTful 搜索引擎。
### [Elasticsearch 快速入门](Elasticsearch快速入门.md)
- [Elasticsearch 面试总结](elasticsearch-interview.md) 💯
- [Elasticsearch 简介](Elasticsearch简介.md)
- [Elasticsearch 快速入门](Elasticsearch快速入门.md)
- [Elasticsearch 基本概念](Elasticsearch基本概念.md)
- [Elasticsearch Rest API](ElasticsearchRestApi.md)
- [Elasticsearch 查询](Elasticsearch查询.md)
- [Elasticsearch 排序](Elasticsearch排序.md)
- [Elasticsearch 聚合](Elasticsearch聚合.md)
- Elasticsearch 分词
- [Elasticsearch 分析器](Elasticsearch分析器.md)
- [Elasticsearch 运维](Elasticsearch运维.md)
- [Elasticsearch 性能优化](Elasticsearch性能优化.md)
### [Elasticsearch 简介](Elasticsearch简介.md)
### [Elasticsearch Rest API](ElasticsearchRestApi.md)
### [Elasticsearch 索引管理](Elasticsearch索引管理.md)
### [Elasticsearch 查询](Elasticsearch查询.md)
### [Elasticsearch 高亮](Elasticsearch高亮.md)
### [Elasticsearch 排序](Elasticsearch排序.md)
### [Elasticsearch 聚合](Elasticsearch聚合.md)
### [Elasticsearch 分析器](Elasticsearch分析器.md)
### [Elasticsearch 运维](Elasticsearch运维.md)
### [Elasticsearch 性能优化](Elasticsearch性能优化.md)
### Elastic 技术栈