一、es相关查询
1、多维度查询 关键词:bool must match
{
"query": {
"bool": {
"must": [
{
"match":{"server_name":"www.test.com"}
},
{
"match":{"status":"404"}
}
]
}
}
}
2、模糊查询 关键词:wildcard
匹配出状态码status 以 5 开头的日志
{
"query": {
"wildcard": {"status": "5*"}
}
}
3、指定某个值 同时匹配多个字段 关键词:multi_match
query 要查询的值
fields 要匹配的字段【数组】
匹配出 字段code和status 为400的所有日志
{
"query": {
"multi_match": {
"query": "400",
"fields": [ "code", "status" ]
}
}
}
4、一个字段查询多个值
关键词:terms
{ “字段”:[ 要匹配的多个值 ] }
{
"query": {
"terms": {
"status": ["400","402","406"]
}
}
}
5、多种组合查询
关键词:bool must should range size sort
{
"query": {
"bool": {
"must": [
{
"bool":{
"should":[
{"wildcard": {"status": "5*"}},
{"terms": {"status": ["400","402","406"]}}
]
}
},
{
"range": {
"time": {"gte": "2022-05-22T12:34:00.000+0800",
"lte": "2022-05-22T12:34:01.000+0800"}
}
}
]
}
},
"size":100,
"sort": [
{
"time": {
"order": "desc"
}
}
]
}
6、es默认时间格式查询/ java时间查询
{
"query": {
"bool": {
"must": [
{
"range": {
"createTime": {
"gte": "2022-05-22T12:34:00.000+0800",
"lte": "2022-05-22T12:34:01.000+0800"
}
}
}
]
}
},
"size":20
}
java 查询时:
实体字段添加: @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
代码中转换格式:SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
新建es格式化date:"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
7、单字段排序
{
"sort": {
"createTime": {
"order": "asc"
}
}
}
8、多字段排序
{
"sort":[{
"createTime": {
"order": "asc"
},
"updateTime": {
"order": "desc"
}]
}
}
9、条件查询加聚合
{
"query": {
"bool": {
"must": [
{
"range": {
"createTime": {
"from": "2022-05-16T00:00:00.000+0800"
}
}
},
{
"match": {
"tonalState": 2
}
}
]
}
},
"aggs": {
"brandAgg": {
"terms": {
"field": "mediaLink"
}
}
},
"size": 0
}
10、高量查询
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
11、自定义高亮
{
"query": {
"term": {
"description": {
"value": "iphone"
}
}
},
"highlight": {
"post_tags": ["</span>"],
"pre_tags": ["<span style='color:red'>"],
"fields": {
"*":{}
}
}
}
12、聚合查询
publicsentiment/_search GET
{
"aggs": {
"mediaLink": {
"terms": {
"field": "mediaLink"
},
"aggs": {
"dataExist": {
"terms": {
"field": "dataExist"
}
}
}
}
},
"size": 0
}
13、查询指定字段
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
GET /heima/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 2699
}
}
}
14、模糊查询(fuzzy)
fuzzy 查询是 term 查询的模糊等价。它允许用户搜索词条与实际词条的拼写出现偏差,但是偏差的编辑距离不得超过2:
GET /heima/_search
{
"query": {
"fuzzy": {
"title": {
"value":"appla",
"fuzziness":1
}
}
}
}
15、elastic的聚合
Elasticsearch中提供的划分桶的方式有很多:
1、Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
2、Histogram Aggregation:根据数值阶梯分组,与日期类似
3、Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
4、Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
综上所述,我们发现bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中往往会嵌套另一种聚合:metrics aggregations即度量
比较常用的一些度量聚合方式:
1、Avg Aggregation:求平均值
2、Max Aggregation:求最大值
3、Min Aggregation:求最小值
4、Percentiles Aggregation:求百分比
5、Stats Aggregation:同时返回avg、max、min、sum、count等
6、Sum Aggregation:求和
7、Top hits Aggregation:求前几
8、Value Count Aggregation:求总数
16、指定间隔分组
interval:间隔,
min_doc_count:过滤为0的分组
{
"size":0,
"aggs":{
"price":{
"histogram": {
"field": "price",
"interval": 5000,
"min_doc_count": 1
}
}
}
}
17、elasticsearch 深分页
产生原因:from、size 两字段过大,es默认是10000
解决方式:
(1)深度分页之scroll,滚动查询、每次请求两条。可以定制 scroll = 5m意味着该窗口过期时间为5分钟。
GET /student/_search?scroll=5m
{
"query": {
"match_all": {}
},
"size": 2
}
后边查询的时候需要带上 _scroll_id 参数
GET /_search/scroll
{
"scroll":"5m",
"scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC0YFmllU"
}
(2)search_after 使用索引全局唯一标识字段 、官方推荐使用 _uid 作为全局唯一值,但是只要能表示其唯一性就可以。
GET /student/_search
{
"query":{
"match_all": {}
},
"size":2,
"sort":[
{
"uid": "desc"
}
]
}
下一次分页,需要将上述分页结果集的最后一条数据的值带上。
GET /student/student/_search
{
"query":{
"match_all": {}
},
"size":2,
"search_after":[1005],
"sort":[
{
"uid": "desc"
}
]
}
18、解决keyword长度报错问题**
test_demo/_mapping
{
"properties": {
"title": {
"type": "keyword",
"ignore_above": 51
}
}
}
深分页对比
分页方式 | 性能 | 优点 | 缺点 | 场景 |
---|---|---|---|---|
from+size | 低 | 灵活性好,实现简单 | 深度分页问题 | 数据量比较小,能容忍深度分页问题 |
scroll | 中 | 解决了深度分页问题 | 无法反应数据的实时性(快照版本),维护成本高,需要维护一个 | 海量数据的导出需要查询海量结果集的数据 |
search_after | 高 | 性能最好、不存在深度分页问题、能够反映数据的实时变更 | 实现复杂,需要有一个全局唯一的字段、连续分页的实现比较复杂,因为每一次查询都需要上次查询的结果 | 海量数据的分页 |
19:时间段包含查询(智能报告热榜数据查询)
{
"query": {
"bool": {
"should": [
{
"bool": {
"should": [
{
"range": {
"createTime": {
"gte": "2024-03-19T11:42:00.000+0800",
"lte": "2024-03-19T11:55:00.000+0800"
}
}
},
{
"range": {
"updateTime": {
"gte": "2024-03-19T11:42:00.000+0800",
"lte": "2024-03-19T11:55:00.000+0800"
}
}
}
],
"minimum_should_match": 1
}
},
{
"bool": {
"must": [
{
"range": {
"createTime": {
"lt": "2024-03-19T11:42:00.000+0800"
}
}
},
{
"range": {
"updateTime": {
"gt": "2024-03-19T11:55:00.000+0800"
}
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}
二、设置非keyword类型字段聚合(只会对新数据生效)
POST /index_name/_mapping
{
"properties": {
"testText": {
"type": "text",
"fielddata": true,
"fields": {
"subField": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
三、ElasticSearch Java API之高级查询(分页查询,高亮查询,正则表达式查询,聚合查询等)
参考:
ElasticSearch Java API之高级查询(分页查询,高亮查询,正则表达式查询,聚合查询等)_java es高级查询分组分页聚合查询-CSDN博客
Java 操作RestHighLevelClient查询详解-CSDN博客
四、ES优化
1、写入速度优化
1、加大 Translog Flush ,目的是降低 Iops 、 Writeblock 。
2、增加 Index Refresh 间隔,目的是减少 Segment Merge 的次数。
3、调整 Bulk 线程池和队列。
4、优化节点间的任务分布。
5、优化 Lucene 层的索引建立,目的是降低 CPU 及 IO。
6、批量写入
7、服务器磁盘读写速度提高
8、调整refresh_interval(刷新时间),默认为1s,若调大后,会消耗更大的heap内存
9、副本越多,写效率越低(index.number_of_replicas: 0)
2、大数据量的优化
(1)动态索引层面
基于模板+时间+rollover api 滚动创建索引,减少单个索引的数据量过大
(2)存储层面
冷热数据分离存储,热数据(比如最近 3 天或者一周的数据),其余为冷数据。
对于冷数据不会再写入新数据,可以考虑定期 force_merge 加 shrink 压缩操作,节省存储空间和检索效率。
(3)部署层面
结合 ES 自身的支持动态扩展的特点,动态新增机器的方式可以缓解集群压力
时间聚合
DateHistogramAggregationBuilder group = AggregationBuilders.dateHistogram("releaseTime")//自定义名称
.dateHistogramInterval(DateHistogramInterval.DAY)//设置间隔
.minDocCount(0)//返回空桶
.timeZone(ZoneId.of("+08:00"))
.field("releaseTime")//指定时间字段
.format("dd日");//设定返回格式