写在前面
最近一段时间都在做druid实时数据查询的工作,本文简单将官网上的英文文档加上自己的理解翻译成中文,同时将自己遇到的问题及解决方法list下,防止遗忘。
本文的demo示例均来源于官网。
Druid查询概述
Druid的查询是使用Rest风格的http请求查询服务节点,客户端通过发送Json对象请求查询接口。可以使用shell脚本查询或通过Google的ARC插件构造Post请求进行查询。
Query构建
Shell脚本
curl -X POST ':/druid/v2/?pretty' -H 'Content-Type:application/json' -d @
其中
ARC插件
见下图
Druid查询
1 Druid查询类型
不同的查询场景使用不同的查询方式。Druid有很多查询类型,对于各种类型的查询类型的配置可以通过配置不同的Query实现。Druid的查询类型,概括为以下3类:
csharp;gutter:true;
1.聚合查询:时间序列查询(Timeseroes),Top查询(TopN),GroupBy查询(GroupBy)
2.元数据查询:时间范围(Time Boundary),段元数据(Segment Metadata),数据源(DataSource)
2.Search查询(Search)</p>
<pre><code>
一般聚合查询使用的较多,其他类型的查询方式使用场景较少且较简单,可直接参考官网给出的[demo](http://druid.io/docs/0.9.2/querying/querying.html)即可查询;本文主要介绍聚合查询。一般情况下,Timeseries和TopN查询性能优于GroupBy,GroupBy查询方式最灵活但是最耗性能。Timeseries查询性能明显优于GroupBy,因为聚合不需要其他GroupBy其他维度;对于Groupby和排序在一个单一维度的场景,TopN优于GroupBy。
## 2 Druid主要查询属性简介
一条Druid query中主要包含以下几种属性:
</code></pre>
<p>1.queryType:查询类型,即timeseries,topN,groupBy等;
2.dataSource:数据源,类似Mysql中的表的概念;
3.granularity:聚合粒度,聚合粒度有none,all,week,day,hour等;
4.filter:过滤条件,类似Mysql中的where条件;
5.aggregator:聚合方式,类似Mysql中的count,sum等操作</p>
<pre><code>
#### 2.1.1 简单的聚合粒度
简单的聚合粒度有:all、none、second、minute、fifteen_minute、thirty_minute、hour、day、week、month、quarter、year;简单聚合粒度的查询取决于druid存储数据的最小粒度,如果构建数据的最小粒度是小时,使用minute粒度去查询,结果数据也是小时粒度的数据。
假设存储在Druid中的数据使用毫秒粒度构建,数据格式如下:
;gutter:true;
{"timestamp": "2013-08-31T01:02:33Z", "page": "AAA", "language" : "en"}
{"timestamp": "2013-09-01T01:02:33Z", "page": "BBB", "language" : "en"}
{"timestamp": "2013-09-02T23:32:45Z", "page": "CCC", "language" : "en"}
{"timestamp": "2013-09-03T03:32:45Z", "page": "DDD", "language" : "en"}
提交一个小时粒度的groupBy查询,查询query如下:
{
"queryType":"groupBy",
"dataSource":"my_dataSource",
"granularity":"hour",
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"2000-01-01T00:00Z/3000-01-01T00:00Z"
]
}
按小时粒度进行的groupby查询结果中timestamp值精确到小时,比小时粒度更小粒度值自动补填零,以此类推按天查询,则小时及小粒度补零。timestamp值为UTC。查询结果如下:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若指定聚合粒度为day,则按照天为单位对数据进行聚合,查询结果如下:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若聚合粒度设置为none,则按照druid中build数据的最小粒度查询数据,即不进行聚合,如bulid数据的粒度是ms,则聚合出来的结果也是毫秒:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若将聚合粒度设置为all,则返回数据的长度为1,即把查询时间段的数据做一个汇总:
[ {
"version" : "v1",
"timestamp" : "2000-01-01T00:00:00.000Z",
"event" : {
"count" : 4,
"language" : "en"
}
} ]
2.1.2 时间聚合粒度
可指定一定的时间段进行聚合,返回UTC时间;支持可选属性origin;不指定时间,默认的开始时间=1970-01-01T00:00:00Z;
持续时间段2小时,从1970-01-01T00:00:00开始:
{"type": "duration", "duration": 7200000}
2.1.3 常用时间段聚合粒度
时间聚合粒度的特例,方便使用,如年、月、日、小时等,日期标准是ISO 8601。无特别指定的情况下,year从1月份开始,month从1号开始,week从周一开始。
一般的格式为:其中timeZone可选,默认值是UTC;origin可选,默认1970-01-01T00:00:00;
{"type": "period", "period": "P2D", "timeZone": "America/Los_Angeles"}
period的一般写法为:
month:P2M代表2个月作为一个聚合粒度;
week:P2W代表2周作为一个聚合粒度;
day:P1D代表1天作为一个聚合粒度;
hour:PT1H代表1个小时作为一个聚合粒度;
minute:PT0.750S代表750s作为一个聚合粒度;
如提交一个1d作为聚合粒度的groupby查询的query:
{
"queryType":"groupBy",
"dataSource":"my_dataSource",
"granularity":{"type": "period", "period": "P1D", "timeZone": "America/Los_Angeles"},
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"1999-12-31T16:00:00.000-08:00/2999-12-31T16:00:00.000-08:00"
]
}
查询得到的结果为:
[ {
"version" : "v1",
"timestamp" : "2013-08-30T00:00:00.000-07:00",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-08-31T00:00:00.000-07:00",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T00:00:00.000-07:00",
"event" : {
"count" : 2,
"language" : "en"
}
} ]
官网给出的例子是以美国洛杉矶的时区为准,一般中国的时区这样使用,更多时区可移步该链接查询:
"granularity": {
"period": "PT1H",
"timeZone": "+08:00",
"type": "period"
}
一个filter即一个json对象,代表一个过滤条件,等价于mysql中的一个where条件;过滤器的类型主要有:Selector filter,Regular expression filter(正则表达式过滤)、Logical expression filters(AND、OR、NOT)、In filter、Bound filter、Search filter、JavaScript filter、Extraction filter;
2.2.1 Selector 过滤器
等价于 WHERE <dimension_string> = '<dimension_value_string>'</dimension_value_string></dimension_string>
json格式:
"filter": { "type": "selector", "dimension": , "value": }
2.2.2 正则表达式 过滤器
类似Selector过滤器,只不过过滤使用的是正则表达式;正则表达式为标准的java正则表达式规范;
"filter": { "type": "regex", "dimension": , "pattern": }
2.2.3 逻辑表达式 过滤器
AND
"filter": { "type": "and", "fields": [, , ...] }
OR
"filter": { "type": "not", "field": }
NOT
"filter": { "type": "not", "field": }
IN
等价于
SELECT COUNT(*) AS 'Count' FROM table
WHERE outlaw
IN ('Good', 'Bad', 'Ugly')
{
"type": "in",
"dimension": "outlaw",
"values": ["Good", "Bad", "Ugly"]
}
BOUND
数值型:21
Original: https://www.cnblogs.com/xlli/p/10021168.html
Author: 梨小落是个小疯子
Title: Druid学习之查询语法
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607746/
转载文章受原作者版权保护。转载请注明原作者出处!