Apache Druid数据查询套件详解计数、排名和分位数计算(送JSON-over-HTTP和 ...

火影  金牌会员 | 2022-9-17 08:37:40 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 905|帖子 905|积分 2715

5. 数据查询

欲看此文,必看如下两篇文章:
Druid支持JSON-over-HTTP和SQL两种查询方式。除了标准的SQL操作外,Druid还支持大量的唯一性操作,利用Druid提供的算法套件可以快速的进行计数,排名和分位数计算。

5.1 准备工作

5.1.1 导入大量数据

准备大量数据提供查询,我们插入1万条随机打车数据
  1. http://localhost:8010/taxi/batchTask/100000
复制代码

5.2.2 查看数据摄取进程

我们发现数据摄取进程正在运行,可以等待数据摄取任务结束

5.3 原生查询

Druid 最开始的时候是不支持 SQL 查询的,原生查询是通过查询 Broker 提供的 http server 来实现的
5.3.1 查询语法
  1. curl -L -H'Content-Type:application/json' -XPOST --data-binary  @<query_json_file> <queryable_host>:<port>/druid/v2/?pretty
复制代码
5.3.2 查询案例

5.3.2.1 编辑查询JSON
  1. # 创建查询目录
  2. mkdir query
  3. # 编辑查询的JSON
  4. vi query/filter1.json
复制代码
json 内容如下
  1. {
  2.     "queryType":"timeseries",
  3.     "dataSource":"message",
  4.     "granularity":"month",
  5.     "aggregations":[
  6.      {
  7.             "type":"count",
  8.             "name":"taxiNum"
  9.      }
  10.     ],
  11.     "filter":{"type":"selector","dimension":"status","value":1},
  12.     "intervals":["2021-06-07/2022-06-07"]
  13. }
复制代码
5.3.2.2 参数解释


  • queryType:查询类型,timeseries代表时间序列查询
  • dataSource:数据源,指定需要查询的数据源是什么
  • granularity:分组粒度,指定需要进行分组的粒度是什么样的
  • aggregations:聚合查询:里面我们聚合了count,对数据进行统计
  • filter:数据过滤,需要查询那些数据
  • intervals:查询时间的范围,注意时间范围是前闭后开的,后面的日期是查询不到的
5.3.2.3 执行查询命令

在命名行中执行下面的命令会将查询json发送到对应的broker中进行查询--data-binary指定的查询json的路径
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter1.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码
我们查询了每个月发起打车的人数有多少

5.4 查询类型

druid查询采用的是HTTP RESTFUL方式,REST接口负责接收客户端的查询请求,客户端只需要将查询条件封装成JSON格式,通过HTTP方式将JSON查询条件发送到broker节点,查询成功会返回JSON格式的结果数据。了解一下druid提供的查询类型
5.4.1 时间序列查询

timeseries时间序列查询对于指定时间段按照查询规则返回聚合后的结果集,查询规则中可以设置查询粒度,结果排序方式以及过滤条件,过滤条件可以使用嵌套过滤,并且支持后聚合。
5.4.1.1 查询属性

时间序列查询主要包括7个主要部分
属性描述是否必须queryType该字符串总是"timeseries"; 该字段告诉Apache Druid如何去解释这个查询是dataSource用来标识查询的的字符串或者对象,与关系型数据库中的表类似。查看数据源可以获得更多信息是descending是否对结果集进行降序排序,默认是false, 也就是升序排列否intervalsISO-8601格式的JSON对象,定义了要查询的时间范围是granularity定义了查询结果的粒度,参见 Granularity是filter参见 Filters否aggregations参见 聚合否postAggregations参见Post Aggregations否limit限制返回结果数量的整数值,默认是unlimited否context可以被用来修改查询行为,包括 Grand TotalZero-filling。详情可以看 上下文参数部分中的所有参数类型否5.4.1.2 案例
  1. {
  2.     "queryType":"topN",
  3.     "dataSource":"taxi_message",
  4.     "dimension":"local",
  5.     "threshold":2,
  6.     "metric":"age",
  7.     "granularity":"month",
  8.     "aggregations":[
  9.      {
  10.         "type":"longMin",
  11.         "name":"age",
  12.         "fieldName":"age"
  13.      }
  14.      ],
  15.     "filter":{"type":"selector","dimension":"sex","value":"女"},
  16.     "intervals":["2021-06-07/2022-06-07"]
  17. }
复制代码
5.4.2 TopN查询

topn查询是通过给定的规则和显示维度返回一个结果集,topn查询可以看做是给定排序规则,返回单一维度的group by查询,但是topn查询比group by性能更快。metric这个属性是topn专属的按照该指标排序。
5.4.2.1 查询属性

topn的查询属性如下
属性描述是否必须queryType该字符串总是"TopN",Druid根据该值来确定如何解析查询是dataSource定义将要查询的字符串或者对象,与关系型数据库中的表类似。 详情可以查看 数据源 部分。是intervalsISO-8601格式的时间间隔,定义了查询的时间范围是granularity定义查询粒度, 参见 Granularities是filter参见 Filters否aggregations参见Aggregations对于数值类型的metricSpec, aggregations或者postAggregations必须指定,否则非必须postAggregations参见postAggregations对于数值类型的metricSpec, aggregations或者postAggregations必须指定,否则非必须dimension一个string或者json对象,用来定义topN查询的维度列,详情参见DimensionSpec是threshold在topN中定义N的一个整型数字,例如:在top列表中返回多少个结果是metric一个string或者json对象,用来指定top列表的排序。更多信息可以参见TopNMetricSpec是context参见Context5.4.2.2 案例

查询每个季度年龄最小的女性的前两个的城市
  1. vi query/topN.json
复制代码
  1. {
  2.     "queryType":"topN",
  3.     "dataSource":"message",
  4.     "dimension":"local",
  5.     "threshold":2,
  6.     "metric":"age",
  7.     "granularity":"quarter",
  8.     "aggregations":[
  9.      {
  10.             "type":"longMin",
  11.             "name":"age",
  12.                  "fieldName":"age"
  13.      }
  14.       ],
  15.     "filter":{"type":"selector","dimension":"sex","value":"女"},
  16.     "intervals":["2021-06-07/2022-06-07"]
  17. }
复制代码
5.4.2.3 执行查询
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/topN.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码

5.4.5 分组查询

在实际应用中经常需要进行分组查询,等同于sql语句中的Group by查询,如果对单个维度和指标进行分组聚合计算,推荐使用topN查询,能够获得更高的查询性能,分组查询适合多维度,多指标聚合查询
5.4.5.1 查询属性

下表内容为一个GroupBy查询的主要部分:
属性描述是否必须queryType该字符串应该总是"groupBy", Druid根据该值来确定如何解析查询是dataSource定义将要查询的字符串或者对象,与关系型数据库中的表类似。 详情可以查看 数据源 部分。是dimension一个用来GroupBy的json List,详情参见DimensionSpec来了解提取维度的方式是limitSpec参见limitSpec否having参见Having否granularity定义查询粒度,参见 Granularities是filter参见Filters否aggregations参见Aggregations否postAggregations参见Post Aggregations否intervalsISO-8601格式的时间间隔,定义了查询的时间范围是subtotalsSpec一个JSON数组,返回顶级维度子集分组的附加结果集。稍后将更详细地描述它。否context参见Context5.4.5.2 案例

每一季度统计年龄在21-31的男女打车的数量
  1. vi query/groupBy.json
复制代码
  1. {
  2.     "queryType":"groupBy",
  3.     "dataSource":"taxi_message",
  4.     "granularity":"Quarter",
  5.     "dimensions":["sex"],
  6.     "aggregations":[
  7.      {
  8.             "type":"count",
  9.             "name":"taxiNum"
  10.      }
  11.     ],
  12.     "filter":{
  13.                 "type":"bound",
  14.                 "dimension":"age",
  15.                 "lower":"21",
  16.                 "upper":"31",
  17.                 "alphaNumeric":true
  18.     },
  19.     "intervals":["2021-06-07/2022-06-07"]
  20. }
复制代码
5.4.5.3 执行查询
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/groupBy.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码

5.5 查询组件

在介绍具体的查询之前,我们先来了解一下各种查询都会用到的基本组件,如Filter,Aggregator,Post-Aggregator,Query,Interval等,每种组件都包含很多的细节
5.5.1 Filter

Filter就是过滤器,在查询语句中就是一个JSON对象,用来对维度进行筛选和过滤,表示维度满足Filter的行是我们需要的数据,类似sql中的where字句。Filter包含的类型如下:
5.5.1.1 选择过滤器

Selector Filter的功能类似于SQL中的where key=value,它的json示例如下
  1. "Filter":{"type":"selector","dimension":dimension_name,"value":target_value}
复制代码
使用案例
  1. vi query/filter1.json
复制代码
  1. {
  2.     "queryType":"timeseries",
  3.     "dataSource":"taxi_message",
  4.     "granularity":"month",
  5.     "aggregations":[
  6.      {
  7.             "type":"count",
  8.             "name":"taxiNum"
  9.      }
  10.     ],
  11.     "filter":{"type":"selector","dimension":"status","value":1},
  12.     "intervals":["2021-06-07/2022-06-07"]
  13. }
复制代码
5.5.1.2 正则过滤器

Regex Filter 允许用户使用正则表达式进行维度的过滤筛选,任何java支持的标准正则表达式druid都支持,它的JSON格式如下:
  1. "filter":{"type":"regex","dimension":dimension_name,"pattern":regex}
复制代码
使用案例,我们搜索姓名包含数字的的用户进行聚合统计
  1. vi query/filter2.json
复制代码
  1. {
  2.     "queryType":"timeseries",
  3.     "dataSource":"taxi_message",
  4.     "granularity":"month",
  5.     "aggregations":[
  6.      {
  7.             "type":"count",
  8.             "name":"taxiNum"
  9.      }
  10.     ],
  11.     "filter":{"type":"regex","dimension":"username","pattern":"[0-9]{1,}"},
  12.     "intervals":["2021-06-07/2022-06-07"]
  13. }
复制代码
执行查询
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter2.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码

5.5.1.3 逻辑过滤器

Logincal Expression Filter包含and,not,or三种过滤器,每一种都支持嵌套,可以构建丰富的逻辑表达式,与sql中的and,not,or类似,JSON表达式如下:
  1. "filter":{"type":"and","fields":[filter1,filter2]}
  2. "filter":{"type":"or","fields":[filter1,filter2]}
  3. "filter":{"type":"not","fields":[filter]}
复制代码
使用案例,我们查询每一个月,进行打车并且是女性的数量
  1. vi query/filter3.json
复制代码
  1. {
  2.     "queryType":"timeseries",
  3.     "dataSource":"taxi_message",
  4.     "granularity":"month",
  5.     "aggregations":[
  6.      {
  7.             "type":"count",
  8.             "name":"taxiNum"
  9.      }
  10.     ],
  11.     "filter":{
  12.         "type":"and",
  13.         "fields":[
  14.             {"type":"selector","dimension":"status","value":1},
  15.             {"type":"selector","dimension":"sex","value":"女"}
  16.         ]
  17.     },
  18.     "intervals":["2021-06-07/2022-06-07"]
  19. }
复制代码
进行数据查询
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter3.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码

5.5.1.4 包含过滤器

In Filter类似于SQL中的in, 比如 where username in('zhangsan','lisi','zhaoliu'),它的JSON格式如下:
  1. {
  2.         "type":"in",
  3.         "dimension":"local",
  4.         "values":['四川省','江西省','福建省']
  5. }
复制代码
使用案例,我们查询每一个月,在四川省、江西省、福建省打车的人数
  1. vi query/filter4.json
复制代码
  1. {
  2.     "queryType":"timeseries",
  3.     "dataSource":"taxi_message",
  4.     "granularity":"month",
  5.     "aggregations":[
  6.      {
  7.             "type":"count",
  8.             "name":"taxiNum"
  9.      }
  10.     ],
  11.     "filter":{
  12.         "type":"in",
  13.         "dimension":"local",
  14.         "values":["四川省","江西省","福建省"]
  15.     },
  16.     "intervals":["2021-06-07/2022-06-07"]
  17. }
复制代码
进行数据查询
  1. curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter4.json http://192.168.64.177:8082/druid/v2/?pretty
复制代码

5.5.1.5 区间过滤器

<blockquote>
Bound Filter是比较过滤器,包含大于,等于,小于三种,它默认支持的就是字符串比较,是基于字典顺序,如果使用数字进行比较,需要在查询中设定alpaNumeric的值为true,需要注意的是Bound Filter默认的大小比较为>=或者

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表