elasticsearch 查询聚合操作

一、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日");//设定返回格式
  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java操作Elasticsearch实现聚合查询,您可以使用Elasticsearch的官方Java客户端库进行操作。以下是一个简单的示例代码,演示如何执行聚合查询: 首先,您需要导入ElasticsearchJava客户端库。您可以通过在项目的构建文件中添加相应的依赖来实现,例如使用Maven: ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.16.3</version> </dependency> ``` 然后,您可以使用以下代码执行聚合查询: ```java import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; public class ElasticsearchAggregationExample { public static void main(String[] args) { // 创建 Elasticsearch 客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder("localhost:9200")); // 构建聚合查询请求 SearchRequest searchRequest = new SearchRequest("your_index_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 添加聚合查询条件 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); searchSourceBuilder.aggregation( AggregationBuilders.terms("by_field") .field("your_field_name") .subAggregation( AggregationBuilders.sum("sum_of_field") .field("your_field_name"))); searchRequest.source(searchSourceBuilder); try { // 执行查询 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 处理聚合结果 Terms terms = searchResponse.getAggregations().get("by_field"); for (Terms.Bucket bucket : terms.getBuckets()) { String fieldKey = bucket.getKeyAsString(); long docCount = bucket.getDocCount(); Sum sum = bucket.getAggregations().get("sum_of_field"); double sumValue = sum.getValue(); // 处理聚合结果 System.out.println("Field: " + fieldKey); System.out.println("Doc Count: " + docCount); System.out.println("Sum of Field: " + sumValue); } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭 Elasticsearch 客户端连接 try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } } ``` 请根据您的实际情况修改代码中的索引名称、字段名称和聚合类型。这个示例代码执行了一个术语(terms)聚合,按照某个字段进行分桶,并在每个桶中进行求和。您可以根据具体需求进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值