[toc]
前言
本文以命令行为主
其本质还是发送http请求去操作数据
1. 基本格式
es是以RESTFul风格来命名API的,其API的基本格式如下:
http://<ip>:<port>/<索引>/<类型>/<文档id>
这里需要注意的是,该格式从es7.0.0开始,移除Type(类型)这个概念,新的基本格式如下:
http://<ip>:<port>/<索引>/_doc/<文档id>
Type(类型)字段那里变为固定值 _doc
es的动作是以http方法来决定的: 常用的http方法: GET/PUT/POST/DELETE
post 主做修改, put主做创建
post也有创建的功能,特别是插入数据生成随机id时
2. 命令
2.1 创建索引
curl -XPUT http://localhost:9200/xkj_test
没有指定mappings,故为非结构化索引,也没有字段
// 结构化索引: 指定了mappings
curl -X PUT 'localhost:9200/accounts' -d '
{
"mappings": { // mappings 映射
"man": { // type
"properties": { // 具体属性
"name": { // 字段名
"type":"text" // 字段类型
// ....还有其他可以选,比如拆分规则,权重值
},
"country": {
"type":"keyword"
},
"age": {
"type":"integer"
},
"date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
},
// "worman": {} // 6.x版本只支持一个type
}
}
}'
其核心是里面的json字符串
2.2 插入数据
curl -X POST 'localhost:9200/accounts/person/1000' -d '
// 这个1000表示id,如果不写es会自动生成一个,如果连索引和类型也没有也会一并创建,如果id已存在则修改
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}'
格式是
ip:port/索引/类型/id
, 参数是各属性的json字符串
2.3 修改数据
post http://localhost:9200/test/_doc/1/_update
{
"script": {
"lang": "painless",
"inline": "ctx._source.age += 30"
}
}
关键字”script”: 标志以脚本的方式修改文档
“lang”:表示以何种脚本语言进行修改,“painless”表示以es内置的脚本语言进行修改。此外es还支持多种脚本语言,如Python,js等等
“inline”:指定脚本内容 “ctx”代表es上下文,_source 代表文档
根据条件修改信息:
POST my_index/_update_by_query
{
"script": {
"source": "ctx._source['ipsub']=0"
},
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "ipsub"
}
}
]
}
}
上面语句是根据是否存在"ipsub"字段,如果不存在,给信息增加字段"ipsub",并且赋值0
2.4 查看
- 查看xkj_test索引数据格式
curl -X GET http://localhost:9200/xkj_test/
- 查看xkj_test索引下指定id查看
curl -X GET 'localhost:9200/xkj_test/person/1000?pretty=true'
- 根据条件查询
curl -X POST 'localhost:9200/accounts/person/_search' -d '
// 要带上 _search 关键字
{
"query" : { "match" : [{ "desc" : "软件" },{ "desc" : "软件 工程" }]}
}'
and 查询: match写多个条件
or 查询: 利用空格的分词,达到or的效果(我猜的)
_score
:匹配度
_source
:文档的字段
es的查询五花八门,最好的技术书籍就是官网,以后好好看,如果要查数据,借助可视化界面就够用了
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
2.5 删除
删除xkj_test索引
delete http://localhost:9200/xkj_test/
删除xkj_test索引下的数据(指定id)
delete http://localhost:9200/xkj_test/_doc/1
根据条件删除xkj_test索引下test1类型的数据
post http://localhost:9200/xkj_test/test1/_delete_by_query
{
"query": {
"range": {
"createDate": {
"lt": "now-31d"
}
}
}
}
解释: 删除 createDate 字段下31天前的数据
利用_delete_by_query插件去批量删除
https://blog.csdn.net/weixin_44034192/article/details/89372934
2.6 简单排序
按照指定字段排序,(默认按照分数排序)
GET books/_search
{
"sort": [
"price": {
"order": "desc"
},
"age": {
"order": "desc"
}
]
}
// 按照价格降序排,再按年龄排
在 Elasticsearch 中,默认排序是按照相关性的评分(_score)进行降序排序,也可以按照字段的值排序、多级排序、多值字段排序、基于 geo(地理位置)排序以及自定义脚本排序,除此之外,对于相关性的评分也可以用 rescore 二次、三次打分,它可以限定重新打分的窗口大小(window size),并针对作用范围内的文档修改其得分,从而达到精细化控制结果相关性的目的。
3. 复杂查询
3.1 Query and filter context
查询子句的行为取决于它是用在查询上下文(query context)还是用在过滤器上下文(filter context):
3.1.1 Query context
在查询上下文中的查询子句回答了“这个文档与这个查询子句的匹配程度是怎样的?”问题。除了决定文档是否匹配以外,查询子句还会计算一个“_score”,它表示文档与其他文档的相关程度(分数)。
3.1.2 Filter context
在过滤器上下文中,一个查询子句回答了“这个文档与查询子句匹配吗?”的问题。这个答案是简单的Yes或者No,也不会计算分数。过滤上下文主要用于过滤结构化数据
PS:Query VS Filter
- 查询反应的是文档与查询子句的匹配程度,而过滤反应的是文档是否匹配查询子句
- 一个是筛选是否满足条件,情况无非两种:是或不是;一个是看满足条件的记录与查询条件的匹配程度
- 哪些满足条件,这是过滤;满足条件的这些记录与条件的匹配程度,这是查询
- 过滤不会计算评分,查询会计算评分
3.2 全文查询( Full text)
3.1.1 match query
match查询接受文本/数值/日期类型的数据,分析它们,并构造一个查询。
相当于模糊查询
match是一种布尔类型的查询。这意味着它对提供的文本进行分析,并在分析的过程中为提供的文本构造一个布尔查询。operator 选项可以设置为 or 或者 and 以此来控制布尔子句(默认是 or )。例如
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match" : {
"skuName" : "空调"
}
}
}'
3.1.2 Match Phrase Query
match_phrase 查询与 match类似,但是它是用于精确匹配或单词接近匹配的。例如:
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match_phrase" : {
"skuName" : "this is a test"
}
}
}'
3.1.3 Multi Match Query
multi_match 相当于 match 的多字段版本, multi_match可以指定多个字段,而match只能针对一个字段
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "skuName" ]
}
}
}
'
fields 里的字段用 * 支持模糊匹配, 写成这种 [ "subject^3", "skuName" ] 表示subject比skuName重要3倍
3.1.4 Query String Query
支持Lucene查询字符串语法,允许指定 AND | OR | NOT ,并且在单个查询字符串中进行多字段查询, 分词后对每个词都查询
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"query_string" : {
"default_field" : "skuName",
"query" : "this that thus"
}
}
}
'
// 在skuName中查询 this , that , thus 三个词 , 其实质解析成: " this OR that OR thus", 你可以替换OR为AND/NOT
// 还可以指定快 例如: "query" : "(new york city) OR (big apple)" 这样将被拆分成 “new york city” 和 “big apple” 两部分,并且每一部分都被分析器独立分析
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"query_string" : {
"fields" : ["content", "name"],
"query" : "this AND that"
}
}
}
'
// 等价于
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"query_string": {
"query": "(content:this OR name:this) AND (content:that OR name:that)"
}
}
}
'
注意,按操作符拆分
query_string的参数包括:
query 实例被解析的查询文本
default_field 如果没有指定前缀字段的话,这是默认的查询字段。(默认查询所有字段)
default_operator 如果没有明确指定操作符的话,那么这是默认的操作符。例如,如果默认操作符是OR的话,那么“my name is jack”将被翻译成“my OR name OR is OR jack”,同理,如果是AND,则被翻译成“my AND name AND is AND jack”
analyzer 用来解析查询字符串的解析器的名字
allow_leading_wildcard 如果设置了,那么 * 或 ? 允许作为第一个字符。默认是true
lenient 如果设置为true,则格式失败将被忽略
3.2 单词级查询(term text)
全文本查询会在执行之前对查询字符串进行分析,而单词级别查询会对存储在反向索引中的精确的term进行操作。
这些查询通常用于结构化的数据,比如:numbers , dates ,enums 等,而不是对全文本字段。
(PS:也就是说,全文本查询之前要先对文本内容进行分词,而单词级别的查询直接在相应字段的反向索引中精确查找,单词级别的查询一般用于数值、日期等类型的字段上)
3.2.1 Term Query
在指定的字段中查找包含指定的精确的term的文档
term查询将在反向索引(或者叫倒排索引)中查找包含特定的精确的term的文档。例如:
curl -X POST "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"term" : { "user" : "Kimchy" }
}
}
'
// 查询倒排索引(切词后)中user包含"kimchy"字符串的值,
3.2.2 Terms Query
查找包含指定字段中指定的任何确切term的文档
筛选出与所提供的terms中任何一个匹配的文档
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"terms" : { "user" : ["kimchy", "elasticsearch"]}
}
}
'
// 查询 切词后包含"kimchy"或者 "elasticsearch"文档
3.2.3 Range Query
查找指定字段在指定范围内包含值(日期、数字或字符串)的文档。
下面的例子返回age字段的值在10到20之间的文档:
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}
'
range查询可以接受下列参数:
gte 大于或等于
gt 大于
lte 小于或等于
lt 小于
boost 设置boost值,默认是1.0
在日期范围查询的时候,我们可以指定日期格式。例如:(时间格式es会自动转化,用字符串去查时间格式也能行)
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"born" : {
"gte": "01/01/2012",
"lte": "2013",
"format": "dd/MM/yyyy||yyyy"
}
}
}
}
'
// 这个例子是查询在2012-01-01到2013-12-31之间出生的人
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"timestamp" : {
"gte": "2015-01-01 00:00:00",
"lte": "now",
"time_zone": "+01:00"
}
}
}
}
'
3.2.4 Exsit Query
在特定的字段中查找非空值的文档
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"exists" : { "field" : "user" }
}
}
'
3.2.5 Prefix Query
查找包含带有指定前缀的term的文档
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"prefix" : { "user" : "ki" }
}
}
'
3.2.6 Wildcard Query
支持通配符查询,*表示任意字符,?表示任意单个字符
这个查询效率比较慢
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"wildcard" : { "user" : "ki*y" }
}
}
'
3.2.7 Regexp Query
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}
'
prefix 和 wildcard 和 regexp 三者工作方式是一样的 ,需要扫描倒排索引中的词列表才能找到所有匹配的词,然后依次获取每个词相关的文档 ID
性能对比: prefix > wildcard > regexp
wildcard 和 regexp要避免左模糊查询
3.3 聚合查询
Elasticsearch 的聚合(Aggregations)功能十分强大,允许在数据上做复杂的分析统计。Elasticsearch 提供的聚合分析功能主要有指标聚合(metrics aggregations)、桶聚合(bucket aggregations)、管道聚合(pipeline aggregations) 三大类,
所有的聚合,无论它们是什么类型,都遵从以下的规则。
- 使用查询中同样的 JSON 请求来定义它们,而且你是使用键 aggregations 或者是 aggs 来进行标记。需要给每个聚合起一个名字,指定它的类型以及和该类型相关的选项。
- 它们运行在查询的结果之上。和查询不匹配的文档不会计算在内,除非你使用 global 聚集将不匹配的文档囊括其中。
- 可以进一步过滤查询的结果,而不影响聚集。
以下是聚合的基本结构:
"aggregations" : { <!-- 最外层的聚合键,也可以缩写为 aggs -->
"<aggregation_name>" : { <!-- 聚合的自定义名字 -->
"<aggregation_type>" : { <!-- 聚合的类型,指标相关的,如 max、min、avg、sum,桶相关的 terms、filter 等 -->
<aggregation_body> <!-- 聚合体:对哪些字段进行聚合,可以取字段的值,也可以是脚本计算的结果 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!-- 元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!-- 在聚合里面在定义子聚合 -->
}
[,"<aggregation_name_2>" : { ... } ]* <!-- 聚合的自定义名字 2 -->
}
- 在最上层有一个 aggregations 的键,可以缩写为 aggs。
- 在下面一层,需要为聚合指定一个名字。可以在请求的返回中看到这个名字。在同一个请求中使用多个聚合时,这一点非常有用,它让你可以很容易地理解每组结果的含义。
- 最后,必须要指定聚合的类型。
关于聚合分析的值来源,可以取字段的值,也可以是脚本计算的结果。
但是用脚本计算的结果时,需要注意脚本的性能和安全性;尽管多数聚集类型允许使用脚本,但是脚本使得聚集变得缓慢,因为脚本必须在每篇文档上运行。为了避免脚本的运行,可以在索引阶段进行计算。
此外,脚本也可以被人可能利用进行恶意代码攻击,尽量使用沙盒(sandbox)内的脚本语言。
text类型默认不支持聚合
查询所有球员的平均年龄是多少,并对球员的平均薪水加 188(也可以理解为每名球员加 188 后的平均薪水)。
POST /player/_search?size=0
{
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
},
"avg_salary_188": {
"avg": {
"script": {
"source": "doc.salary.value + 188"
}
}
}
}
}
// 默认情况下,包含聚合的搜索会返回搜索命中和聚合结果, size 表示返回命中的文档数量,设为0表示只返回聚合结果
3.3.1 Metrics aggregations
指标聚合(又称度量聚合)主要从不同文档的分组中提取统计数据,或者,从来自其他聚合的文档桶来提取统计数据。
这些统计数据通常来自数值型字段,如最小或者平均价格。用户可以单独获取每项统计数据,或者也可以使用 stats 聚合来同时获取它们。更高级的统计数据,如平方和或者是标准差,可以通过 extended stats 聚合来获取。
3.3.1.1 Min Aggregation
Min Aggregation 用于最小值统计。例如,统计 sales 索引中价格最低的是哪本书,查询语句如下:
GET /sales/_search?size=0
{
"aggs" : {
"min_price" : {
"min" : {
"field" : "price"
}
}
}
}
聚合结果如下:
{
...
"aggregations": {
"min_price": {
"value": 18.0
}
}
}
3.3.1.2 Max Aggregation
Max Aggregation 用于最大值统计。例如,统计 sales 索引中type是hat的且价格最高的是哪本书,并且计算出对应的价格的 2 倍值,查询语句如下:
GET /sales/_search?size=0
{
"query" : {
"constant_score" : {
"filter" : {
"match" : { "type" : "hat" }
}
}
},
"aggs" : {
"max_price" : {
"max" : {
"field" : "price" ,
"missing": 60
}
},
"max_price_2" : {
"max" : {
"field" : "price",
"script": {
"source": "_value * 2.0"
}
}
}
}
}
指定的 field,在脚本中可以用 _value 取字段的值。
如果指定字段没有值,可以通过 missing 指定默认值;若未指定默认值,缺失该字段值的文档将被忽略(计算)。
聚合结果如下:
{
...
"aggregations": {
"max_price": {
"value": 188.0
},
"max_price_2": {
"value": 376.0
}
}
}
3.3.1.3 Avg Aggregation
Avg Aggregation 用于计算平均值。例如,统计 exams 索引中考试的平均分数,
GET /exams/_search?size=0
{
"aggs" : {
"avg_grade" : {
"avg" : {
"field" : "grade"
}
}
}
}
{
...
"aggregations": {
"avg_grade": {
"value": 78.0
}
}
}
除了常规的平均值聚合计算外,elasticsearch 还提供了加权平均值的聚合计算, 详情参见 Elasticsearch 指标聚合之 Weighted Avg Aggregation 。
用加权平均值代替原本值
3.3.1.4 Sum Aggregation
Sum Aggregation 用于计算总和。
GET /exams/_search?size=0
{
"aggs" : {
"hat_prices" : {
"sum" : { "field" : "price" }
}
}
}
{
...
"aggregations": {
"hat_prices": {
"value": 567.0
}
}
}
3.3.1.5 Count Aggregation
Count Aggregation 可按字段统计文档数量。例如,统计 books 索引中包含 author 字段的文档数量,查询语句如下:
GET /books/_search?size=0
{
"aggs" : {
"doc_count" : {
"value_count" : { "field" : "author" }
}
}
}
{
...
"aggregations": {
"doc_count": {
"value": 5
}
}
}
3.3.1.6 Cardinality Aggregation
Cardinality Aggregation 用于基数统计,其作用是先执行类似 SQL 中的 distinct 操作,去掉集合中的重复项,然后统计排重后的集合长度。
例如,在 books 索引中对 language 字段进行 cardinality 操作可以统计出编程语言的种类数,查询语句如下:
GET /books/_search?size=0
{
"aggs" : {
"all_lan" : {
"cardinality" : { "field" : "language" }
},
"title_cnt" : {
"cardinality" : { "field" : "title.keyword" }
}
}
}
假设 title 字段为文本类型(text),去重时需要指定 keyword,表示把 title 作为整体去重,即不分词统计。
{
...
"aggregations": {
"all_lan": {
"value": 8
},
"title_cnt": {
"value": 18
}
}
}
3.3.1.7 Stats Aggregation
Stats Aggregation 用于基本统计,会一次返回 count、max、min、avg 和 sum 这 5 个指标。例如,在 exams 索引中对 grade 字段进行分数相关的基本统计,查询语句如下:
GET /exams/_search?size=0
{
"aggs" : {
"grades_stats" : {
"stats" : { "field" : "grade" }
}
}
}
3.3.1.8 Extended Stats Aggregation
Extended Stats Aggregation 用于高级统计,和基本统计功能类似,但是会比基本统计多出以下几个统计结果,sum_of_squares(平方和)、variance(方差)、std_deviation(标准差)、std_deviation_bounds(平均值加/减两个标准差的区间)。在 exams 索引中对 grade 字段进行分数相关的高级统计,查询语句如下:
GET /exams/_search?size=0
{
"aggs" : {
"grades_stats" : {
"extended_stats" : { "field" : "grade" }
}
}
}
3.3.1.9 Percentiles Aggregation
Percentiles Aggregation 用于百分位统计。百分位数是一个统计学术语,如果将一组数据从大到小排序,并计算相应的累计百分位,某一百分位所对应数据的值就称为这一百分位的百分位数。默认情况下,累计百分位为 [ 1, 5, 25, 50, 75, 95, 99 ],也可以用percents
指定范围。以下例子给出了在 latency 索引中对 load_time 字段进行加载时间的百分位统计,查询语句如下:
GET latency/_search
{
"size": 0,
"aggs" : {
"load_time_outlier" : {
"percentiles" : {
"field" : "load_time" ,
"percents":[30,45] //查询第30%和45%的数据
}
}
}
}
需要注意的是,如上的 load_time
字段必须是数字类型。
{
...
"aggregations": {
"load_time_outlier": {
"values" : {
"1.0": 5.0,
"5.0": 25.0,
"25.0": 165.0,
"50.0": 445.0,
"75.0": 725.0,
"95.0": 945.0,
"99.0": 985.0
}
}
}
}
第1%位的数据是5
第5%位的数据是25
……
第99%位的数据是99
3.3.1.10 Percentiles Ranks Aggregation
Percentiles Ranks Aggregation 与 Percentiles Aggregation 统计恰恰相反,就是想看当前数值处在什么范围内(百分位), 假如你查一下当前值 500 和 600 所处的百分位,发现是 90.01 和 100,那么说明有 90.01 % 的数值都在 500 以内,100 % 的数值在 600 以内。
GET latency/_search
{
"size": 0,
"aggs" : {
"load_time_ranks" : {
"percentile_ranks" : {
"field" : "load_time",
"values" : [500, 600]
}
}
}
}
同样 load_time
字段必须是数字类型。
{
...
"aggregations": {
"load_time_ranks": {
"values" : {
"500.0": 90.01,
"600.0": 100.0
}
}
}
}
可以设置 keyed
参数为 true
,将对应的 values 作为桶 key 一起返回,默认是 false
。
GET latency/_search
{
"size": 0,
"aggs": {
"load_time_ranks": {
"percentile_ranks": {
"field": "load_time",
"values": [500, 600],
"keyed": true
}
}
}
}
{
...
"aggregations": {
"load_time_ranks": {
"values": [
{
"key": 500.0,
"value": 90.01
},
{
"key": 600.0,
"value": 100.0
}
]
}
}
}
3.3.2 bucket aggregations
bucket 可以理解为一个桶,它会遍历文档中的内容,凡是符合某一要求的就放入一个桶中,分桶相当于 SQL 中的 group by。从另外一个角度,可以将指标聚合看成单桶聚合,即把所有文档放到一个桶中,而桶聚合是多桶型聚合,它根据相应的条件进行分组。
桶数最多 65536 个,可修改
3.3.2.1 Terms Aggregation
Terms Aggregation 用于词项的分组聚合。最为经典的用例是获取 X 中最频繁(top frequent)的项目,其中 X 是文档中的某个字段,如用户的名称、标签或分类。由于 terms 聚集统计的是每个词条,而不是整个字段值,因此通常需要在一个非分析型的字段上运行这种聚集。原因是, 你期望“big data”作为词组统计,而不是“big”单独统计一次,“data”再单独统计一次。
支持字段类型 Keyword, Numeric, ip, boolean, binary.
用户可以使用 terms 聚集,从分析型字段(如内容)中抽取最为频繁的词条。还可以使用这种信息来生成一个单词云。
{
"aggs": {
"profit_terms": {
"terms": {
"field": "skuName"
}
}
}
}
结果:
{
...
"aggregations": {
"genres": {
"doc_count_error_upper_bound": 0, // 错误文档的个数
"sum_other_doc_count": 0, // 未统计的文档个数
"buckets": [
{
"key": "electronic",
"doc_count": 6
},
{
"key": "rock",
"doc_count": 3
},
{
"key": "jazz",
"doc_count": 2
}
]
}
}
}
返回值中,默认按doc_count数量降序排序, 可以用order字段指定排序规则
可以用size字段控制返回的桶数
3.2.2.2 Filter Aggregation
Filter Aggregation 是过滤器聚合,可以把符合过滤器中的条件的文档分到一个桶中,即是单分组聚合。
{
"aggs": {
"age_terms": {
"filter": {"term":{"gender":"F"}},
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
}
}
}
}
}
在聚合操作中加入过滤,比 过滤后再聚合要差, 上面的效率比下面的效率要差
POST /sales/_search?size=0&filter_path=aggregations
{
"query": { "term": { "type": "t-shirt" } },
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
3.2.2.3 Filters Aggregation
Filters Aggregation 是多过滤器聚合,可以把符合多个过滤条件的文档分到不同的桶中,即每个分组关联一个过滤条件,并收集所有满足自身过滤条件的文档。
{
"size": 0,
"aggs": {
"messages": {
"filters": {
"filters": {
"errors": { "match": { "body": "error" } },
"warnings": { "match": { "body": "warning" } }
}
}
}
}
}
在这个例子里,我们分析日志信息。聚合会创建两个关于日志数据的分组,一个收集包含错误信息的文档,另一个收集包含告警信息的文档。而且每个分组会按月份划分。
filters 写多个过滤器比 写过filter效率好
3.2.2.4 Range Aggregation
Range Aggregation 范围聚合是一个基于多组值来源的聚合,可以让用户定义一系列范围,每个范围代表一个分组。在聚合执行的过程中,从每个文档提取出来的值都会检查每个分组的范围,并且使相关的文档落入分组中。注意,范围聚合的每个范围内包含 from 值但是排除 to 值。
{
"aggs": {
"age_range": {
"range": {
"field": "age",
"ranges": [{
"to": 25
},
{
"from": 25,
"to": 35
},
{
"from": 35
}]
},
"aggs": {
"bmax": {
"max": {
"field": "balance"
}
}
}
}
}
}
}
3.2.2.5 Date Range Aggr
日期范围聚合是专用于日期值的范围聚合。该聚合和正常的 范围 聚合的区别主要在于:该聚合可以用 日期数学 表达式表示 from 值 和 to 值,还可以指定 返回 from 和 to 响应字段的日期格式。注意,该聚合包含 from 值,但不包含 to 值。(左闭右开的区间)
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"format": "MM-yyyy",
"ranges": [
{ "to": "now-10M/M" },
{ "from": "now-10M/M" }
]
}
}
}
}
to: < 现在减去 10 个月,向下舍入到月初
from: >= 现在减去 10 个月,向下舍入到月初
在上面的例子中,我们创建了两个范围桶,第一个桶会将早于 10 个月之前的所有文档存储,第二个桶会将从 10 月之前开始的文档存储。
{
...
"aggregations": {
"range": {
"buckets": [
{
"to": 1.4436576E12,
"to_as_string": "10-2015",
"doc_count": 7,
"key": "*-10-2015"
},
{
"from": 1.4436576E12,
"from_as_string": "10-2015",
"doc_count": 0,
"key": "10-2015-*"
}
]
}
}
}
时间格式和java的一样
3.2.2.6 Range Aggr
基于多桶值源的聚合,使用户能够定义一组范围 - 每个范围代表一个桶。 在聚合过程中,将从每个文档中提取的值根据每个存储区范围进行检查,并将相关/匹配文档“存储”到“存储区”中。 请注意,该聚合包含 from 值,但不包含 to 值
GET /_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 100.0 },
{ "from": 100.0, "to": 200.0 },
{ "from": 200.0 }
]
}
}
}
}
结果:
{
...
"aggregations": {
"price_ranges": {
"buckets": [
{
"key": "*-100.0",
"to": 100.0,
"doc_count": 2
},
{
"key": "100.0-200.0",
"from": 100.0,
"to": 200.0,
"doc_count": 2
},
{
"key": "200.0-*",
"from": 200.0,
"doc_count": 3
}
]
}
}
}
3.4 复合查询
复合查询包装其他复合查询或叶查询,以组合它们的结果和分数,改变它们的行为,或者从查询切换到过滤上下文。
简单的说是 将多种查询条件组合到一起
3.4.1 Bool query
filter
子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。(过滤掉不要的数据)
must
子句(查询)必须出现在匹配的文档中,并将有助于得分。(用来做匹配的,表示需要出现在文档里)
must_not
子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。
should
子句(查询)应出现在匹配的文档中。【注意should的最小匹配数】
关于should子句,特别要注意:
如果这个布尔查询位于
query context
,并且有must或者filter子句,那么即使should子句没有匹配任何文档,也没关系如果是位于
filter context
,或者既没有must也没有filter,那么至少有"指定"个should查询必须匹配文档。这个行为可以通过设置minimum_should_match
参数来显式地控制。(至少满足几个should子句), 可以是正负整数/正负百分比等各种比例 (默认值是0)
GET product/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"sellPrice": {
"gte": 1
}
}
}
],
"must": [
{
"match": {
"skuName": "空调"
}
}
]
}
}
, "_source": "skuName"
}
// 查询skuName中"空调"的文档,并且过滤出sellPrice大于等于1的文档
filter 子句类可包含 bool query,实现更复杂的逻辑, (俄罗斯套娃之深圳分套)
// 多个条件
GET service-java-logs-2021.07.16/_search
{
"_source": "message",
"query": {
"bool": {
"must": [
{
"match_phrase": {
"message": "ERROR"
}
}
],
"must_not": [
{
"wildcard": {
"message": "*navigation*"
}
},
{
"match": {
"message": "defaultParameterMap"
}
},
{
"match": {
"message": "parameters"
}
}
],
"filter": [
{
"term": {
"log.file.path.keyword": "/opt/online-shop-manage/logs/online-shop-manage-provider.log"
}
}
]
}
}
}
3.4.2 boosting query
来源:
https://www.cnblogs.com/hong-fithing/p/11221020.html
http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
https://www.cnblogs.com/hirampeng/p/10035858.html
https://www.cnblogs.com/cjsblog/p/9910788.html
https://www.knowledgedict.com/tutorial/elasticsearch-sort.html