草庐IT

ES聚合统计group by,sum,max,min,avg,count等聚合统计

絮落锦乡 2023-04-24 原文

基本查询

通过match实现全文搜索

{FIELD} - 就是我们需要匹配的字段名

{TEXT} - 就是我们需要匹配的内容

{
  "query": {
    "match": {
      "{FIELD}": "{TEXT}"
    }
  }
}

通过term实现精确搜索

{FIELD} - 就是我们需要匹配的字段名

{TEXT} - 就是我们需要匹配的内容

{
  "query": {
    "term": {
      "field": "value"
    }
  }
}

类似sql

select * from zyzkwjj where field = "value"

通过terms实现SQL的in搜索

{
  "query": {
    "terms": {
      "{FIELD}": [
        "{VALUE1}",
        "{VALUE2}"
      ]
    }
  }
}

{FIELD} - 就是我们需要匹配的字段名

{VALUE1}, {VALUE2} .... {VALUE N} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型。

类似sql

select * from zyzkwjj where field in( "value1","value2"....)

通过range实现范围搜索,类似SQL语句中的>, >=, <, <=表达式

{
  "query": {
    "range": {
      "{FIELD}": {
        "gte": value1, 
        "lte": value2
      }
    }
  }
}

参数说明:

{FIELD} - 字段名

gte范围参数 - 等价于>=

lte范围参数 - 等价于 <=

范围参数可以只写一个,例如:仅保留 "gte": value1, 则代表 FIELD字段 >= value1

范围参数如下:

gt - 大于 ( > )

gte - 大于且等于 ( >= )

lt - 小于 ( < )

lte - 小于且等于 ( <= )

类似sql

select * from zyzkwjj where field >=value1 and field<=value2

bool组合查询搜索,类似SQL中的and (且)、or (或)语法

{
  "query": {
    "bool": { // bool查询
      "must": [], // must条件,类似SQL中的and, 代表必须匹配条件
      "must_not": [], // must_not条件,跟must相反,必须不匹配条件
      "should": [] // should条件,类似SQL中or, 代表匹配其中一个条件
    }
  }
}

参数说明

must条件,类似SQL中的and, 代表必须匹配条件

{
  "query": {
    "bool": {
      "must": [
         {匹配条件1},
         {匹配条件2},
         ...可以有N个匹配条件...
        ]
    }
  }
}
{
  "query": {
    "bool": {
      "must": [
          {
            "term": {
              "qzh":  "001"
            }
          },
          {
            "term": {
              "ajh":  "0001"
            }
          }
        ]
    }
  }
}

类似sql

select * from zyzkwjj where qzh="001" and ajh="0001"

must_not条件,跟must相反,必须不匹配条件

{
  "query": {
    "bool": {
      "must_not": [
         {匹配条件1},
         {匹配条件2},
         ...可以有N个匹配条件...
        ]
    }
  }
}
{
  "query": {
    "bool": {
      "must_not": [
          {
            "term": {
              "qzh":  "001"
            }
          },
          {
            "term": {
              "ajh":  "0001"
            }
          }
        ]
    }
  }
}

类似sql

select * from zyzkwjj where qzh!="001" and ajh!="0001"

should条件,类似SQL中or, 代表匹配其中一个条件

{
   "query": {
     "bool": {
       "should": [
          {匹配条件1},
          {匹配条件2},
          …可以有N个匹配条件…
         ]
     }
   }
 }
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "qzh": "001"
          }
        },
        {
          "match": {
            "ajh": "0001"
          }
        }
      ]
    }
  }
}

类似sql

select * from zyzkwjj where qzh="001" or ajh="0001"

bool综合查询

{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "qzh": "001"
                }
              },
              {
                "range": {
                  "nd": {
                    "gte": 2000,
                    "lte": 2020
                  }
                }
              }
            ]
          }
        },
        {
          "terms": {
            "ajh": [
              "0001",
              "0002"
            ]
          }
        }
      ]
    }
  }
}
select * from zyzkwjj where (qzh='001' and (nd>=2000 and nd<=2020)) or ajh in ("0001","0002")

wildcard模糊匹配,使用时需要加*通配,跟SQL的%类似

{
    "query": {
        "wildcard": {
            "ztm": "*测试*"
        }
    }
}
查询的字段类型是string类型,对应ES中的text,keyword(这种查询方式会慢,查询不进行分词处理)

match_phrase_prefix模糊匹配SQL的like类似

{
    "query": {
        "match_phrase_prefix": {
            "ztm": "测试"
        }
    }
}

multi_match (match 查询的升级版,可以指定多个字段查询,也可以添加权重,更倾向于匹配哪个字段)

{
    "query": {
        "multi_match": {
            "query": "测试",
            "fields": ["zrz","ztm"]
        }
    }
}

{
    "query": {
        "multi_match": {
            "query": "测试",
            "fields": ["zrz^10","ztm"]
        }
    }
}

query_string query中可以使用Lucene 查询方式,选择and 、or、not等

{
    "query": {
        "query_string": {
            "default_field": "ztm",
            "query": "测试 or 归档"
        }
    }
}

simple_query_string query_string 的升级,可以直接使用 +、|、- 代替 AND、OR、NOT 等。

{
    "query": {
        "simple_query_string": {
            "default_field": "ztm",
            "query": "测试 + 归档"
        }
    }
}

GEO地理信息查询

ES的地理信息存储的核心是:

坐标点 geo_point(坐标点,经纬度)

geo_bounding_box 在地图上画一个有规则的矩形,搜索被矩形包含的坐标点对应的文档记录。

geo_distance给出一个坐标点和距离,搜索出这个距离范围内的相关文档。

geo_polygon 在地图上画一个不规则的多边形,搜索被多边形包含的坐标点对应的文档

地理形状 geo_shape(点、线、面、圆、椭圆等)

geo_shape以图形的方式存储地理信息(图形就是无数个点组成的,可以是点、线、多边形、圆等)

交集 匹配图形重叠(默认方式)。
不重叠 匹配图形不重叠。
包含 匹配图形包含另外一个图形。

常用的数学几何逻辑查询:

按距离查询(坐标之间的距离,比如打车软件,外面软件,方圆多少公里等需求)

坐标点跟地理形状的包含关系(一个坐标点是否在是同一个点、是否在一条线上、是否在面里)

地理形状的包含关系(线之间的交叉点、面的交集,包含关系)

ES图形存储geo_shape

点point

圆形circle

矩形envelope

多边形 polygon

使用图形必须定义索引字段类型为geo_shape

点point存储

{
    "location" : {
        "type" : "point", 
        "coordinates" : [113.41,29.58]
    }
}
coordinates数据格式:[经度, 纬度]

圆形circle存储

{
    "location" : {
        "type" : "circle", 
        "coordinates" : [113.41,29.58], 
        "radius" : "2km"
    }
}
coordinates数据格式:[经度, 纬度](圆心)。 radius 标注圆形的半径,单位支持 km、m

矩形envelope存储

{
    "location" : {
        "type" : "envelope", 
        "coordinates" : {
            [113.41,29.58],
            [123.41,39.58]
        }, 
        
    }
}
coordinates数据格式:[经度, 纬度] 第一个值是左上角坐标,第二个是右下角坐标

多边形polygon存储

{
    "location" : {
        "type" : "polygon", 
        "coordinates" : [
            [
                [113.41,29.58],
                [123.41,39.58],
                [133.41,49.58]
                ......
            ],
            [
                [116.41,34.58],
                [128.41,45.58],
                [130.41,47.58]
                ......
            ]
        ], 
        
    }
}
coordinates数据格式:[经度, 纬度] 点坐标,可以有N个,是个多层数组,类似一个多边形漏斗,外轮廓、内轮廓....

地理坐标geo_point(索引创建时指定字段类型为geo_point)

单独进行存储lat 纬度,lon经度

{
  "location": { 
    "lat": 29.58,
    "lon": 113.41
  }
}

数组存储 遵循 [经度,纬度] 的顺序

{
  "location": [113.41,29.58]
}

字符串存储 遵循 纬度,经度

{
  "location": "29.58,113.41"
}

距离搜索geo_distance,_geo_distance排序(支持km、m)

以location中的坐标为中心,距离这个坐标点2km之内的点都找出来

{
    "query": {
        "bool": {
            "filter": {
                "geo_distance": {
                    "distance": "2km",
                    "location": {
                        "lat": 29.58,
                        "lon": 113.41
                    }
                }
            }
        }
    },
    "sort": [
        {
            "_geo_distance": {
                "location": {
                    "lat": 39.889916,
                    "lon": 116.379547
                },
                "order": "asc"
            }
        }
    ]
}
distance,标注查询的范围,支持km,m。filter禁掉相关度计算,缓存结果

矩形图形检索geo_bounding_box(地图上画一个矩形图形,查出图形中所包含的所有坐标)

{
  "query": {
    "bool": { 
      "filter": { 
        "geo_bounding_box": { 
          "location": { 
            "top_left": { 
              "lat": 29.58,
              "lon": 113.41
            },
            "bottom_right": { 
              "lat": 39.58,
              "lon": 123.41
            }
          }
        }
      }
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 29.58,
          "lon": 113.41
        },
        "order": "asc" 
      }
    }
  ]
}
top_left 是矩形左上角坐标,bottom_right 是矩形右下角坐标

多边形图形检索geo_polygon

{
    "query": {
        "bool": {
            "filter": {
                "geo_polygon": {
                    "location": {
                        "points": [
                            {
                                "lat": 29.58,
                                "lon": 113.41
                            },
                            {
                                "lat": 39.58,
                                "lon": 123.41
                            },
                            {
                                "lat": 49.58,
                                "lon": 133.41
                            }
                        ]
                    }
                }
            }
        }
    }
}
points 是数组,可以标注多个点连成面,形成多边形

通用图形检索

intersects 查询的形状与文档的形状有重叠(默认)。

disjoint - 查询的形状与文档的形状完全不重叠。

within - 查询的形状包含文档的形状。

{
    "query": {
        "bool": {
            "filter": {
                "geo_shape": {
                    "location": {
                        "shape": {
                            "type": "envelope",
                            "coordinates": [
                                [
                                    113.41,
                                    29.58
                                    
                                ],
                                [
                                    117.41,
                                    39.58
                                ]
                            ]
                        },
                        "relation": "within"
                    }
                }
            }
        }
    }
}

ES排序

{
  "query": {
    ...查询条件....
  },
  "sort": [
    {
      "{Field1}": { // 排序字段1
        "order": "desc" // 排序方向,asc或者desc, 升序和降序
      }
    },
    {
      "{Field2}": { // 排序字段2
        "order": "desc" // 排序方向,asc或者desc, 升序和降序
      }
    }
    ....多个排序字段.....
  ]
}

{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "zyzkwjj.nd": { // 嵌套对象,使用 点 连接字段名即可
        "order": "desc"
      }
    }
  ]
}

{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "qzh": {
        "order": "desc"
      }
    },
    {
      "ajh": {
        "order": "asc"
      }
    }
  ]
}

类似sql

select * from zyzkwjj order by qzh desc,ajh asc

分组聚合统计(类似sql的group by)

terms类似SQL的group by,根据字段唯一值分组。

histogram根据数值间隔分组,例如: 年龄按10间隔分组,0、10、20、30等等。

date_histogram根据时间间隔分组,例如:按月、按天、按小时分组。

range按数值范围分组,例如: 0-50一组,50-100一组,100-150一组。

桶聚合一般不单独使用,都是配合指标聚合一起使用,对数据分组之后肯定要统计桶内数据,在ES中如果没有明确指定指标聚合,默认使用Value Count指标聚合,统计桶内文档总数。

terms聚合

{
  "aggs": {
    "qzh_census": { // 聚合查询的名字,随便取个名
      "terms": { // 聚合类型为: terms
        "field": "qzh" // 根据qzh字段值,分桶
      }
    }
  }
}

{
    "query": {
        "bool": {
            "must_not": [
                {
                    "term": {
                        "ajh": ""
                    }
                }
            ]
        }
    },
    "aggs": {
        "popular_qzh": {
            "terms": {
                "size":300,
                "field": "qzh"
            }
        }
    }
}

类似sql

select qzh,count(qzh) from zyzkwjj where ajh!="" limit 0,300;

注:must_not 相当于【不等于】,分组聚合统计默认只展示10条数据,可以在terms 中加上size进行分页提取数据。如果在外部添加size 那说明是获取指定的size的值得记录数进行分组统计例如以下示例

{
    "query": {
        "bool": {
            "must_not": [
                {
                    "term": {
                        "ajh": ""
                    }
                }
            ]
        }
    },
    "from": 0,
    "size": 5000,
    "aggs": {
        "popular_qzh": {
            "terms": {
                "size":300,
                "field": "qzh"
            }
        }
    }
}

类似sql

select p.qzh,count(p.qzh) from (select qzh from zyzkwjj where ajh!="" limit 0,5000) p group by p.qzh limit 0,300;

histogram聚合(直方图)

{
    "aggs" : {
        "nds" : { // 聚合查询名字,随便取一个
            "histogram" : { // 聚合类型为:histogram
                "field" : "nd", // 根据nd字段分桶
                "interval" : 2 // 分桶的间隔为2,意思就是nd字段值按2间隔分组
            }
        }
    }
}

date_histogram聚合(直方图)

{
    "aggs" : {
        "sales_over_time" : { // 聚合查询名字,随便取一个
            "date_histogram" : { // 聚合类型为: date_histogram
                "field" : "date", // 根据date字段分组
                "calendar_interval" : "month", // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
                "format" : "yyyy-MM-dd" // 设置返回结果中桶key的时间格式
            }
        }
    }
}

range聚合

{
    "aggs" : {
        "nd_ranges" : { // 聚合查询名字,随便取一个
            "range" : { // 聚合类型为: range
                "field" : "nd", // 根据nd字段分桶
                "ranges" : [ // 范围配置
                    { "to" : 2010 }, // 意思就是 nd <= 2010的文档归类到一个桶
                    { "from" : 2011, "to" : 2015 }, // nd>2011 and nd<2015的文档归类到一个桶
                    { "from" : 2015 } // nd>2015的文档归类到一个桶
                ]
            }
        }
    }
}

指标聚合value_count、max、min、avg、sum等

value Count 类似sql的count函数,统计总数

cardinality 类似SQL的count(DISTINCT 字段), 统计不重复的数据总数

avg 求平均值

sum 求和

max 求最大值

min 求最小值

value_count函数统计文档数量

{
  "aggs": {
    "value_count_census": { // 聚合查询的名字,随便取个名字
      "value_count": { // 聚合类型为:value_count
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select count(qzh) from zyzkwjj

cardinality函数统计文档数量

{
  "aggs": {
    "cardinality_census": { // 聚合查询的名字,随便取个名字
      "cardinality": { // 聚合类型为:cardinality
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select count(DISTINCT qzh) from zyzkwjj
注:sql的count是不会丢失精度而ES的cardinality基数聚合统计的总数是一个近似值,会有一定的误差,这么做的目的是为了性能,因为在海量的数据中精确统计总数是非常消耗性能的,所以得出的值是一个近似值。

avg函数统计文档数量

{
  "aggs": {
    "avg_census": { // 聚合查询的名字,随便取个名字
      "avg": { // 聚合类型为:avg
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select avg(qzh) from zyzkwjj

sum函数统计文档数量

{
  "aggs": {
    "sum_census": { // 聚合查询的名字,随便取个名字
      "sum": { // 聚合类型为:sum
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select sum(qzh) from zyzkwjj

max函数统计文档数量

{
  "aggs": {
    "max_census": { // 聚合查询的名字,随便取个名字
      "max": { // 聚合类型为:max
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select max(qzh) from zyzkwjj

min函数统计文档数量

{
  "aggs": {
    "min_census": { // 聚合查询的名字,随便取个名字
      "min": { // 聚合类型为:min
        "field": "qzh" // 统计qzh这个字段值的总条数
      }
    }
  }
}

类似sql

select min(qzh) from zyzkwjj

示例

{
  "size": 0, // size = 0,代表不想返回query查询结果,只要统计结果
  "query": { // 设置query查询条件,后面的aggs统计,仅对query查询结果进行统计
    "constant_score": {
      "filter": {
        "match": {
          "nd": "2023"
        }
      }
    }
  },
  "aggs": { // 统计query查询结果, 默认情况如果不写query语句,则代表统计所有数据
    "hat_qzhs": { // 聚合查询名字,计算qzh总和
      "sum": {
        "field": "qzh"
      }
    },
    "min_qzh": { // 聚合查询名字,计算qzh最小值
      "min": { 
        "field": "qzh" 
      }
    },
    "max_qzh": { // 聚合查询名字,计算qzh最大值
      "max": { 
        "field": "qzh"
      }
    }
  }
}

有关ES聚合统计group by,sum,max,min,avg,count等聚合统计的更多相关文章

  1. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  2. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  3. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  4. ruby - Rails Elasticsearch 聚合 - 2

    不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a

  5. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  6. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  7. ruby - 如何获取我的 Sinatra 应用程序的代码覆盖率统计信息? - 2

    我编写了一个Sinatra应用程序(网站),我想收集网站代码的代码覆盖率信息。我是Ruby的新手,但Google告诉我rcov是一个很好的代码覆盖工具。不幸的是,我在网上可以找到的所有信息只显示了如何获取有关测试用例的代码覆盖率信息-我想要有关我的站点本身的代码覆盖率信息。我想要分析的特定站点文件位于“sdk”和“sdk/vendor”目录中,因此我通常使用“rubysite.rb”运行我的站点的地方我改为尝试以下操作:rcov-Isdk-Isdk/vendorsite.rb它显示了Sinatra启动文本,但随后立即退出,而不是像我的Sinatra应用程序通常那样等待网络请求。有人能告

  8. ruby-on-rails - 删除 rspec 中的测试 - 更改(模型,:count) failing - Why is reload needed? - 2

    TLDR:App.count需要重新加载才能看到创建的记录。为什么?我找到了很多关于测试DELETE方法的引用资料,如下所示:expect{delete_request}.tochange(App,:count).by(-1)这是有道理的,并且适用于一些类似的场景。但是,我在测试不应该执行的删除时遇到了一个问题,例如当没有用户登录时。我从这里开始,用两种方法来测试同一件事:require'rails_helper'RSpec.describeV1::AppsController,type::controllerdolet(:user){create(:user)}let(:app){c

  9. sql - 如何模拟ActiveRecord Model.count.to_sql - 2

    我想显示一个计数中使用的SQL。但是,Model.count.to_sql将不起作用,因为count返回一个没有to_sql方法的FixNum。我认为最简单的解决方案是这样做:Model.where(nil).to_sql.sub(/SELECT.*FROM/,"SELECTCOUNT(*)FROM")这会创建与Model.count中使用的SQL相同的SQL,但它是否会导致进一步的问题?例如,如果我添加一个复杂的where子句和一些连接。有更好的方法吗? 最佳答案 你可以试试Model.select("count(*)asmode

  10. ruby-on-rails - 收集 Rails 应用程序使用统计信息的最佳方式 - 2

    我有一个Rails应用程序,用户可以在其中设置他们的域并在其中发布内容。我需要收集公共(public)流量统计信息,例如网页浏览量等。此功能的一个很好的例子是我作为客户可以看到的flickr使用统计信息。问题是收集使用信息的最佳方式是什么。应该通过解析日志文件来完成还是应该在运行时收集并存储在数据库中?是否有任何工具或Rails插件已经提供了此功能?此解决方案应该可以很好地扩展,即使每月有数千个域和数百万次网页浏览。 最佳答案 GoogleAnalytics可能是您最好的选择... 关于

随机推荐