Elasticsearch
分布式全文检索引擎
一、使用场景
- 信息搜索
- 电商网站
- 求职网站
- 新闻网站
- 日志收集、分析 - ELK
- 数据分析 - 商品销量、访问量、消费金额
二、核心概念
- Index 索引 - Database 数据库
- Shard 索引分片
- 一个 Shard 对应一个 Lucene 的 Index
- 一个 Shard 都有一个 translog
- Type 类型 (即将废除) - Table 表
- Document 文档 - Row 数据行
- Field 字段 - Column 字段
- Mapping 映射 - Scheme 字段约束
三、API
URL 加上 ?explain 可以查看语句错误原因
1. Index 索引
- 创建索引 - PUT /索引名称
- 判断索引是否存在 - HEAD /索引名称
- 查看索引属性
- 单个 - GET /索引名称
- 多个 - GET /索引名称1,索引名称2,索引名称3
- 所有 - GET _all
- 所在分片状态 - GET /_cat/indices?v
- 启用索引 - POST /索引名称/_open
- 关闭索引 - POST /索引名称/_close
- 删除索引 - DELETE /索引名称1,索引名称2,索引名称3
- 索引迁移 - POST _reindex
- version_type
- 【默认】internal - 直接迁移,碰到已存在文档则进行覆盖
- external - 保留 version 信息迁移,碰到已存在文档对 version 进行更新
- op_type
- create - 碰到已存在文档,提示错误
- conflicts
- proceed - 碰到已存在文档,错误消息提示,只提示文档冲突数量
- query - 支持 数据过滤、排序、数量 设置
- version_type
2. Mapping 映射
- 创建映射 - PUT /索引名称/_mapping
PUT /索引库名/_mapping
{
"properties": {
"字段名": {
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
PUT /lagou-company-index/_mapping/
{
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"job": {
"type": "text",
"analyzer": "ik_max_word"
},
"logo": {
"type": "keyword",
"index": "false"
},
"payment": {
"type": "float"
}
}
}
-
查看映射关系 - GET /索引名称/_mapping
-
查看所有映射关系
- GET _mapping
- GET all/_mapping
-
修改映射关系 - PUT /索引名称/_mapping
- 只能增加映射字段,不能更改
- 如需更改,只能删除重建映射
-
同时创建索引及映射关系 - PUT /索引名称
3. Document 文档
-
添加文档
- 指定 ID - POST /索引名称/_doc/{id}
- 自动生成 ID - POST /索引名称/_doc
-
查看文档
- ID 查找 - GET /索引名称/_doc/{id}
- 条件查找 - GET/索引名称/_search
- 返回属性过滤 - GET /索引名称/_doc/{id} ?_source=属性1,属性2
-
更新文档
- 全局更新(原数据删除后添加) - PUT /索引名称/_doc/{id} - id 不存在则添加
- 局部更新(修改单一字段) - POST /索引名称/_update/{id}
-
删除文档
- 指定 ID - DELETE /索引名称/_doc/{id}
- 条件过滤 - POST /索引名称/_delete_by_query
-
批量查找
- GET /_mget
- GET /索引名称/_mget
-
批量增、删、改 - POST /_bulk {"方法": { "_index" : "索引名称", "_id" : "id编号"}} {"data"}
-
create - 添加文档
-
index - 添加文档、全文替换文档 - 相当于 PUT
-
update - 局部更新文档
-
delete - 删除文档
建议一次更新 1000 ~ 5000 个文档,大小 5 ~ 15 M
-
四、Mapping 属性
-
type 类型
-
String 字符串
- text - 分词,不可聚合
- keyword - 不分词,可聚合
-
Numberical 数值
- byte
- short
- interger
- long
- double
- float
- half_float
- scaled_float - 高精度,需指定精度因子
-
Date 日期 - 【建议】使用 long 保存毫秒值
-
Array 数组
- 匹配时,数组中任一元素满足,则认为满足
- 排序时,升序使用数组中最小元素排序,降序使用数组中最大元素排序
-
Object 对象
-
geo_point 经纬度
-
-
index 是否索引 - 是否可用于搜索 - 【默认】true
-
store 是否存储 - 数据是否独立存储,加快解析速度,但费空间 - 【默认】false
-
analyer 分词器
- 中文
- ik_max_word【常用】 - 最细粒度
- ik_smart - 最粗粒度
- 中文
-
dynamic 动态(遇到陌生字段)映射方式
- true - 自动映射
- false - 忽略
- strict - 报错
-
date_detection 是否关闭日期检测 - 设为 false 时,字符串将始终为 string 类型
-
dynamic_date_formats 设置字符串转换日期规则
-
dynamic_templates 不同字段或数据类型,使用不同的映射
-
refresh_interval 索引刷新频率 - 【默认】1秒
-
index.translog.durability translog 刷盘方式 - 【默认】sync
-
index.translog.sync_interval translog 刷盘间隔 - 【默认】 5秒
PUT /索引库名称
{
"settings":{
"number_of_shards": 分片数量,
"number_of_replicas": 副本数量,
"refresh_interval": "索引刷新频率",
"index.translog.durability": "async",
"index.translog.sync_interval": "5s"
},
"mappings":{
"dynamic": "动态映射方式",
"date_detection": 是否关闭日期检测,
"dynamic_date_formats": "MM/dd/yyyy",
"properties":{
"字段名":{
"映射属性名":"映射属性值"
}
},
}
}
五、查找类型
POST /索引库名/_search
{
"query":{
"查找类型":{
"查找条件":"查找条件值"
}
},
"sort": [
{"要排序的字段": {"order": "asc"}}
],
"highlight": {
"pre_tags": "<font color='pink'>",
"post_tags": "</font>",
"fields": [{"要高亮的字段":{}}]
},
"from": 当前页数,
"size": 每页条数
}
-
match_all - 查找所有
-
match - 将查找条件分词查找,词条间关系为 or - 改为 and 需使用 operator 属性
-
match_phrase - 将查找条件分词,目标文档需包含所有分词且顺序一致
-
multi_match - 将查找条件分词查找,词条间关系为 or,可指定查找 field
- 可使用 * 描述 field - *_name
- 可使用 ^ 加强 field 权重 - subject^3
-
term - 不分词查找
-
query_string - 可指定字段或全文搜索,可使用 AND、OR、~ 操作符切分字符串
-
range - 范围查找,用于查找数字、日期
-
exists - 非空查找
-
prefix - 前缀匹配查找
-
wildcard - 通配符查找
-
regexp - 正则查找
-
fuzzy - 模糊查找
-
bool - 复合查找
- must - 必须包含
- filter - 必须包含,不影响评分,会被缓存到内存,重复查找速度加快
- should - 应该包含
- must_not - 必须不包含,不影响评分
-
dis_max - 多个搜索域分数,只取最高分作为评分 - 默认多个搜索域分数相加
-
suggest - 建议查找
-
completion - 查找条件前缀匹配,给出建议
-
preserve_separators - 查找条件是否保留分割符
- preserve_position_increments - 当建议词的第一个词是停用词时,是否忽略停用词
-
phrase - 将查找条件分词后,判断与原文的匹配程度给出建议
-
term - 将查找条件进行分词,并为每个词条给出建议
- missing - 当词条在词典中找不到,才给出建议
- always - 不论词条在词典中是否找到,都给出建议
- popular - 不论词条在词典中是否找到,都给出词频更高的建议
-
context - 与 completion 相似,增加类别进一步过滤
生产建议 :
completion → 零匹配 → phase → 零匹配 → term
-
六、聚合分析
"aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元数据 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合 -->
}
[,"<aggregation_name_2>" : { ... } ]*<!--聚合的名字 -->
}
1. 统计方式
- 指针聚合 metric
- 桶聚合 bucketing - 先对数据进行分组,再进行聚合统计
2. 统计指针
- 最大值 max
- 最小值 min
- 和 sum
- 平均值 avg
- 计数 count
- 文档字段有值计数 value_count
- 去重计数 cardinality
- 基本统计 stats - 包含 max、min、sum、avg、count
- 高级统计 extended_stats - 包含 平方和、方差、标准差
- 百分占比统计 percentiles - 可指定百分位
- 区间百分比统计 percentile_ranks
七、分布式集群
1. 角色
- Cluster 集群 - 多个 Node 组成,集群中的每个 Node 都有一个共同的集群名称作标示
- Node 节点
- master - 是否有资格竞选主节点 - 【默认】 true
- data - 是否保存数据 - 【默认】 true
- Shard 分片 - 索引的数据分块
- 主分片数量不可变,除非重建索引
- 默认每个主分片都有一个副本分片,且两个分片不在一个节点上
2. 特色
- 新节点自动发现
- 节点对等 - 每个节点都能接收请求,接收请求后将请求转发到存放数据的其它节点上
- 当节点当机,透过副本分片对缺失数据进行恢复
- 搜索时间百毫秒内
3. 搭建规划
原则
-
30G JVM 内存,分片最大容量设为 30G,再根据数据量推算总分片数量 【主分片数量不可变,除非重建索引】
-
总分片数量 除 1.5 ~ 3 为 节点数量
-
副本数量 2,保证高可用
-
当查找性能下降,可增加副本数,提高并发查找能力
应用
-
搜索功能 - 数据量 千万 ~ 十亿 - 2~4个节点
-
联机处理分析 - ELK - 数据量 千亿 - 几十~上百个节点
4. 一致性保证
- ?wait_for_active_shards=同步分片数量&timeout=超时时长
八、关联关系
- Application-side join 应用连接 - 索引之间独立 - 适用少量文档纪录
- Data denormalization 非规范化嵌套文档、Nested objects 嵌套文档
- 透过字段冗于,牺牲索引性能换取查找性能
- 冗于字段应很少改变
- 适合少量关系处理
- 适用读多写少场景
- Parent/child relationships 父子文档
- 牺牲查找性能换取索引性能
- 查找不能同时返回父子文档
- 父子文档必须在同一分片上
- 适用写多读少场景
九、持久化
-
refresh
- 将内存 buffer 写入到一个新的 segment 中,使索引变成可检索状态
- 【默认】每 1 秒运行一次
-
flush
-
将所有 segment 刷盘,并清空 translog 日志,并创建提交点
-
【默认】每 30 分钟运行一次
当节点崩溃并重启时,将从提交点重放 translog 日志,以恢复数据
-
十、并发控制
- 内置版本号 - ?if_seq_no=版本号&if_primary_term=1
- 自定义版本号 - ?version=版本号&version_type=external
十一、分页方案
- from + size - 常用分页方法,深度分页会出现性能问题
- scroll - 将所有符合条件的搜索结果缓存起来 - 不适合实时搜索,适合后台批处理
- search after - 根据上一页最后一条数据确定下一页位置 - 不能跳页
十二、性能优化
- 首次灌入数据,副本数设置为 0
- 自动生成 doc ID,避免读盘操作
- 不重要字段 不分词、不索引
- 调整索引刷新时间间隔 - 默认 1 秒