目录
一篇文章入门 elasticsearch
发展历史
- 2012 0.19.0 接口偏复杂
- 2015 1.6 效率提升亿条数据1秒查询
- 2016 2.3.0 稳定成熟版本,文档比较多,对很多公司来说已部署实例都是2.3.0,想使用新版本需要升级带来的影响
- 当前 7.1.1
elasticsearch是什么
全球最受环境的全文搜索引擎,基于Lucene 构建的开源的、分布式、RESTful接口全部搜索引擎、分布式文档数据库。
集群视角
从应用和管理者角度分别看es集群
es 类比 Mysql
相同点:
索引 = 数据库
类型 = 表
文档 = 记录
字段 = 字段
不同点:
es可以使用索引正则请求多个索引。比如 new_dmp_forecase_*
- Node 独立部署实例
组合一: 只用于数据存储和数据查询,降低其资源消耗率
node.master: false
node.data: true
组合二: 来协调各种创建索引请求或者查询请求,但不存储任何索引数据
node.master: true
node.data: false
组合三: 主要用 于查询负载均衡, 并请求分发到多个指定的node服务器,并对各个node服务器返回的结果进行一个汇总处理,最终返回给客户端
node.master: false
node.data: false
组合四: 即有成为主节点的资格,又存储数据
node.master: true
node.data: true
- Shard 存储文档的空间 默认5个master主分片、5个replica副本分片,共10个分片
index.number_of_shards 决定你的存储容量计算方式是你的预估容量/50G
number_of_replicas 是副本数一般设置1
index.refresh_interval 是写入es后被查询到的时机间隔,一般是10s
分布式搜索原理
首先在随机节点上转发请求,然后查询指定副本分片,然后返回到查询节点返回。
如果集群中一台机器资源被打满,会导致关联查询受影响。
如何提升集群性能?
1、提高机器资源
2、增加副本
3、增加主分区,但需要重建索引
4、增加新的索引
全文搜索原理:倒排索引
查找"live",先对词典二元查找,找到该词,通过指向频率文件的指针读取所有文章号。然后返回结果。词典非常小,因而,整个过程是毫秒级的。
索引结构(desc table)
- 单分片最大存储 max(int32) -128,约21亿条文档
- 映射可以预先定义也可以,第一次存储时自动识别
- 主键ID,可以用作update的记录号
索引映射管理 mapping(create table)
设置映射
mapping可以自动支持动态映射(自动根据json类型映射)、显式映射(明确指定)
显式映射
如果未指定的字段put到文档,就叫动态映射
更新字段映射规则
- 对现有字段不会进行更新
- 新增属性增加到对象数据类型中
- 新多领字段添加到现有字段中
设置索引模板
索引模板就是创建好一个索引参数设置和映射的模板。然后创建索引时直接指定模板名称就好
以后再创建 te 开头的索引时,会自动基于以上配置生效。
基本CURD
PUT /ecommerce/product/1
{
"name" : "gaolujie yagao",
"desc" : "gaoxiao meibai",
"price" : 30,
"producer" : "gaolujie producer",
"tags": [ "meibai", "fangzhu" ]
}
PUT /ecommerce/product/1
{
"name" : "jiaqiangban gaolujie yagao",
"desc" : "gaoxiao meibai",
"price" : 30,
"producer" : "gaolujie producer",
"tags": [ "meibai", "fangzhu" ]
}
DELETE /ecommerce/product/1
GET /ecommerce/product/_search
{
"query" : {
"bool" : {
"must" : {
"match" : {
"name" : "yagao"
}
},
"filter" : {
"range" : {
"price" : { "gt" : 25 }
}
}
}
}
}
GET /ecommerce/product/_search
{
"query" : {
"match" : {
"producer" : "yagao producer"
}
}
}
GET /ecommerce/product/_search
{
"query" : {
"match_phrase" : {
"producer" : "yagao producer"
}
}
}
GET /ecommerce/product/_search
{
"query" : {
"match" : {
"producer" : "producer"
}
},
"highlight": {
"fields" : {
"producer" : {}
}
}
}
另外大部分查询语句都可通过ElasticSearch-SQL( 插件自动生成dsl语句)
核心字段类型
-
字符串数据类型 分为全文字(用于分词搜索)和关键字(用于排序与聚合), 可以给一个字段创建一个对象存放两类数据,如果你既想term查询,又想全文检索的话。
-
日期数据类型 可以设置支持的日期传入格式,但是输出时会默认使用第一个数据格式。
设置分析器
停止词是指文本中出现的频率非常高的词汇,对携带信息不产生影响。比如:a、the、of
- analyzer 用于索引所有条款,包括停止词
- search_analyzer 非短语查询,将删除停止词
- search_quote_analyzer 短语查询,不会删除停止词
测试效果:
短语查询
关键词查询
构建复杂的查询
踩过的坑
- 预估数据量和存储量 选择 按天、按月、按年创建。比如:dos_order_201818。
- 避免按天的索引长期存储 每索引5个shard,shard 过多会影响集群性能。
- 查询时不索引名,尽量明确指定索引,而不是带*查询
- 尽量多带条件进行查询
曾经的一个慢查询,后期发现有其他替代方案,最后弃用了查询。
{
"from": 0,
"size": 1,
"query": {
"bool": {
"must": {
"bool": {
"must": [
{
"match": {
"city_id": {
"query": 12,
"type": "phrase"
}
}
},
{
"range": {
"timestamp": {
"from": 1558713600,
"to": null,
"include_lower": false,
"include_upper": true
}
}
}
]
}
}
}
},
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
- 使用 _routing 直接命中指定Shard上
curl -XPOST 'http://localhost:9200/store/order?routing=user123' -d '
{
"productName": "sample",
"customerID": "user123"
}'
-
只更改了mapping 没有更改 template,会造成每次自动创建的索引mapping不一致。
-
分页查询使用滚动查询
第一次查询时
curl 'http://localhost:9200/secilog/log/_search?scroll=1m&pretty' -d '{
"query": {
"term": {
"message": "text"
}
}
}'
第二次查询
curl 'http://localhost:9200/_search/scroll?pretty' -d '{
"scroll" : "1m",
"scroll_id" : "cXVlcnlBbmRGZXRjaDsxOzExMjo1azRqYldqOVJmYTdIdlVWSk94X2FnOzA7"
}'
- 聚合数据为了控制资源占用,所以最好1万条以内,如果超过怎么办理?可以考虑预先处理
{
"from": 0,
"size": 0,
"query": {
"bool": {
"must": {
"bool": {
"must": [
{
"match": {
"city_id": {
"query": 12,
"type": "phrase"
}
}
}
]
}
}
}
},
"aggregations": {
"day_time_hms": {
"terms": {
"field": "day_time_hms",
"size": 10000
}
}
}
}
- 使用script脚本
{
"from": 0,
"size": 0,
"query": {
"bool": {
"must": {
"bool": {
"must": [{
"bool": {
"should": [{
"match": {
"dt": {
"query": "2019-04-08",
"type": "phrase"
}
}
}]
}
}, {
"bool": {
"should": [{
"match": {
"logic_flow_id": {
"query": "048f88e19f8fb7bd22cdb58ccb29f7a6",
"type": "phrase"
}
}
}]
}
}]
}
}
}
},
"_source": {
"includes": ["dt", "hour", "SUM"],
"excludes": []
},
"fields": ["dt", "hour"],
"aggregations": {
"dt": {
"terms": {
"field": "dt",
"size": 200
},
"aggregations": {
"hour": {
"terms": {
"field": "hour",
"size": 0
},
"aggregations": {
"quota": {
"sum": {
"script": {
"inline": "if (doc['speed'].value == 0) {return 0} else if(doc['logic_flow_id'].value == '048f88e19f8fb7bd22cdb58ccb29f7a6') {return 523/doc['speed'].value} "
}
}
}
}
}
}
}
}
}
参考文档:
https://blog.csdn.net/ctwy291314/article/details/81391514
《Elasticsearch技术解析与实战》
《Elasticsearch In Action》