本文介绍多值数据查询方法。
多值模型数据查询 mquery
请求路径和方法
请求路径 | 请求方法 | 描述 |
/api/mquery | POST | 查询数据 |
多值模型数据和原来写入的单值模型数据不兼容。单值模型数据需要通过原有的/api/put
接口进行写入。同时多值写入数据需要通过/api/mquery
接口进行查询,单值写入的数据需要通过/api/query
进行查询。
请求内容
名称 | 类型 | 是否必选 | 描述 | 默认值 | 举例 |
start | Long | 是 | 开始时间,单位为秒或者毫秒。判断规则详见下面的“时间戳说明”。 | 无 | 1499158925 |
end | Long | 否 | 结束时间,单位为秒或者毫秒。判断规则详见下面的“时间戳说明”。默认值为TSDB服务器当前时间。 | 当前时间 | 1499162916 |
queries | Array | 是 | 子查询数组。 | 无 | 见子查询说明 |
msResolution | boolean | 否 | 子查询数组。 | false | 该参数只对原始数据单位是秒的查询生效。当该参数设置为true时,查询结果中的时间戳会转换为毫秒,否则仍保留原始时间单位,对于原始数据是毫秒的查询,返回结果中时间戳始终为毫秒。 |
hint | Map | 否 | 查询Hint化。 | 无 | 见查询Hint化说明。 |
时间戳说明
时间戳的单位可以是秒或者毫秒。TSDB会通过数值大小来判断时间戳的单位,规则如下:
时间戳区间为 [4284768,9999999999]:判断为秒,表示的日期时间区间为:[1970-02-20 00:59:28,2286-11-21 01:46:39] 。
时间戳区间为 [10000000000,9999999999999]:判断为毫秒,表示的日期时间区间为:[1970-04-27 01:46:40.000,,2286-11-21 01:46:39.999] 。
时间戳区间为 (-∞,4284768)和(9999999999999,+∞):判断为非法时间戳区间。
说明适用于写入数据 (
/api/put
&/api/mput
)和查询数据(/api/query
&/api/mquery
)两个接口。
单时间点数据查询
TSDB支持单时间点数据查询。您可以将开始时间和结束时间设置为相同的数值。
例如:"start":1356998400
,"end":1356998400
。
子查询 JSON 格式
名称 | 类型 | 是否必选 | 描述 | 默认值 | 举例 |
metric | String | 是 | 指标名。 | 无 | wind |
fields | List | 是 | 域查询信息。 | 无 | - |
rate | Boolean | 否 | 是否计算指定指标值的增长速率,计算公式:Vt-Vt-1/t1-t-1。 | false | true |
delta | Boolean | 否 | 是否计算指定指标值的差值,计算公式:Vt-Vt-1。 | false | true |
limit | Integer | 否 | 数据分页,子查询每条时间序列返回数据点的最大数目。 | 0 | 1000 |
offset | Integer | 否 | 数据分页,子查询每条时间序列返回数据点的偏移量。 | 0 | 500 |
dpValue | String | 否 | 根据提供条件过滤返回数据点,支持“>”,“<”, “=”,”<=”, “>=”, “!=”。 | 无 | >=1000 |
preDpValue | String | 否 | 根据提供的条件在扫描原始数据点时进行过滤,支持”>”, “<”, “=”,”<=”, “>=”, “!=”。 说明 它与 | 无 | >=1000 |
downsample | String | 否 | 时间维度降采样。 | 无 | 60m-avg |
tags | Map | 否 | 指定查询标签过滤,和filters冲突。 | 无 | - |
filters | List | 否 | 过滤器,和tags冲突。 | 无 | - |
hint | Map | 否 | 查询Hint化。 | 无 | 见查询Hint化说明 |
一个查询中能够包含的总的
Field
个数最多不超过200个。 示例如下:假设现有一个查询包含3个子查询,第一个子查询包含3个
Field
,第二个子查询包括2个Field
,第三个子查询包含6个Field
,那么这个查询包含的总的Field
个数totalFields=3+2+6=11
,即查询时需要保证totalFields
不能大于200。tags
和filters
都指定的场景下,后指定的过滤条件生效。
域查询信息 JSON 格式
名称 | 类型 | 是否必选 | 描述 | 默认值 | 举例 |
aggregator | String | 是 | 聚合函数,详见下面的“聚合(Aggregate)说明”。 | 无 | sum |
field | String | 是 | 域名称,”*”代表查询指标下所有域。 | 无 | - |
alias | String | 否 | 域名称在返回结果中新名字。 | 无 | - |
downsample | String | 否 | 时间维度降采样。 | 无 | 60m-avg |
rate | Boolean | 否 | 是否计算指定指标值的增长速率,计算公式: Vt-Vt-1/t1-t-1。 | false | true |
dpValue | String | 否 | 根据提供条件过滤返回数据点,支持“>”、“<”、 “=”、“<=”、“>=”、 “!=”。 | 无 | >=1000 |
where | String | 否 | 当域查询信息的field指定为通配符“*”时,该字段用于指定过滤最终查询结果时针对哪个字段进行过滤。其本质与 | 无 | f1>=100 |
关于 limit
、dpValue
、downsample
、tags
和filters
的详细信息请见下面的相关说明。
查询示例
请求:POST/api/mquery
请求体
{
"start" : 1346846400,
"end" : 1346846411,
"msResolution" : true,
"queries" : [
{
"metric" : "wind",
"fields" : [
{
"field" : "speed",
"aggregator" : "sum",
"downsample" : "2s-last",
"alias" : "speed_sum"
},
{
"field" : "*",
"aggregator" : "sum",
"downsample" : "2s-count",
"where":"speed>10"
}
]
}
]
}
数据分页查询(Limit 和 Offset)说明
Limit:子查询每条时间序列返回数据点的最大数目。默认值是0,代表不限制返回点数量。
Offset:子查询每条时间序列返回数据点的偏移量。默认值也是0,代表不偏移返回的数据点。
limit和offset不能为负数。
limit和offset是对最后多值返回结果的分页查询处理,而不是对某一域查询结果进行处理。
示例
返回第1001到1500的数据点,则limit设为500,offset设为1000。
{
"start" : 1346846400,
"end" : 1346846411,
"msResolution" : true,
"queries" : [
{
"metric" : "wind",
"fields" : [
{
"field" : "*",
"aggregator" : "sum",
"downsample" : "2s-count"
}
],
"filters" : [
{
"filter" : "IOTE_8859_0005|IOTE_8859_0004",
"tagk" : "sensor",
"type" : "literal_or"
}
],
"limit" : 500,
"offset" : 1000
}
]
}
值过滤(dpValue) 说明
根据用户设置的数值限制条件,过滤最终的返回数据点。支持 “>”、“<”、 “=”、 “<=”、 “>=”、 “!=”。
不同 fields 之间的 dpValue 关系是“或”。“和”的关系暂时不支持。
字符串仅支持“=”、“!=”。
示例
{
"start" : 1346846400,
"end" : 1346846411,
"msResolution" : true,
"queries" : [
{
"metric" : "wind",
"fields" : [
{
"field" : "level",
"aggregator" : "avg",
"downsample" : "2s-avg",
"dpValue" : ">=8.0"
}
],
"filters" : [
{
"filter" : "IOTE_8859_0005|IOTE_8859_0004",
"tagk" : "sensor",
"type" : "literal_or"
}
]
}
]
}
差值(delta)说明
当用户在子查询中指定差值算子的时候,TSDB返回的数据的dps
中的key-value
对的value
值将是计算所得的差值。
如果未指定差值时返回的dps
中有n
个key-value
对,那么计算完差值后返回的dps
中将只包含n-1
个key-value
对(第一个key-value
对因无法求差值将被舍去)。差值算子对于Downsample
后的值也同样适用。
用户指定了差值算子时,还可以进一步在子查询中指定deltaOptions
来对求差值的行为进行进一步控制。当前支持的deltaOptions
如下所示:
名称 | 类型 | 是否必选 | 描述 | 默认值 | 举例 |
counter | Boolean | 否 | 当该标记位被指定时,则表示假定用于计算差值的指标值,被用户视作是一个类似计数器的单调递增(或递减)的累计值(服务器并不会加以检查)。 | false | true |
counterMax | Integer | 否 | 当counter被设置为true时,该值用于指定差值的阈值。当差值的绝对值超过该阈值时将被视作异常值,该值不指定时则对差值不设阈值。 | 无 | 100 |
dropReset | Boolean | 否 | 该标记位需要与上述 | false | true |
示例
{
"start":1346046400,
"end":1347056500,
"queries":[
{
"aggregator":"none",
"downsample":"5s-avg",
"delta":true,
"deltaOptions":{
"counter":true,
"counterMax":100
}
"metric":"sys.cpu.0",
"dpValue":">=50",
"tags":{
"host":"localhost",
"appName":"hitsdb"
}
}
]
}
降采样(Downsample)说明
当查询的时间范围比较长,只需要返回每个时间间隔的统计值时使用。查询结果返回的时间戳是按照查询指定的间隔对齐后的时间区间起始值。查询格式如下:
<interval><units>-<aggregator>[-fill policy]
指定了降采样后,查询指定的起始时间范围会自动按照指定的interval
区间向前后取整对齐。例如,指定时间戳范围为[1346846401,1346846499] ,指定的interval
为5m,则查询真实的时间戳范围为[1346846101,1346846799]。
其中:
interval
:指数值,如 5、60等,特殊的“0all”表示时间维度聚合为一个点。units
:s代表秒,m代表分,h代表小时,d代表天,n代表月,y代表年。说明默认按照时间戳取模对齐,即“对齐时间戳=数据时间戳-(数据时间戳 % interval)”。
支持基于日历时间间隔的降采样。要使用日历界限,您需要在时间单位units后添加一个
c
。例如,1dc
代表从当日零点到次日零点之间的 24 小时。
aggregator
:降采样使用的算子及其说明如下表所示。
算子 | 描述 |
avg | 平均值。 |
count | 数据点数。 |
first | 取第一个值。 |
last | 取最后一个值。 |
min | 最小值。 |
max | 最大值。 |
sum | 求和。 |
zimsum | 求和。 |
rfirst | 功能同 |
rlast | 功能同 |
rmin | 功能同 |
rmax | 功能同 |
当降采样的聚合算子指定为rfirst
, rlast
, rmin
或rmax
时,不能再在降采样表达式中指定fill policy
。
Fill policy
Fill policy
即填值。降采样先把所有时间线按照指定精度切分,并把每个降采样区间内的数据做一次运算,降采样后如果某个精度区间没有值,fill policy
可以指定在这个时间点填充具体的值。比如某条时间线降采样后的时间戳为:t+0,t+20,t+30,此时如果不指定fill policy
,只有3个值,如果指定了fill policy
为null
,此时间线会有4个值,其中t+10时刻的值为null
。Fill policy
与具体填充值的对应如下表所示。
Fill Policy | 填充值 |
none | 默认行为,不填值。 |
nan | NaN |
null | null |
zero | 0 |
linear | 线性填充值。 |
previous | 之前的一个值。 |
near | 邻近的一个值。 |
after | 之后的一个值。 |
fixed | 用指定的一个固定填充值(请参照下面示例)。 |
Fixed Fill Policy
使用方法:将固定的填充值写到 “#”之后。填充值支持正负数。格式如下:
<interval><units>-<aggregator>-fixed#<number>
示例:1h-sum-fixed#6
, 1h-avg-fixed#-8
降采样示例
示例:1m-avg
,1h-sum-zero
,1h-sum-near
在域查询信息中,downsample
不是必要条款。您甚至可以在查询时明确标明其值为null
或者空("")
,例如:{"downsample": null}
或者 {"downsample": ""}
,这样就不会触发数据点降采样。但是,如果又一个域查询使用了downsample
,在同一子查询下的所有域查询信息都需要包括 downsample
并且采用同样的降采样区间。
聚合(Aggregate)说明
在降采样后会得到多条时间线的值,并且这些时间线的时间戳是对齐的,而聚合就是把多条时间线的值按各个对齐时刻聚合为一条时间线的结果(注意:如果只有一条时间线,则不进行聚合)。聚合时必须要求每条时间线在对应时刻都有值,如果某条时间线在某个时刻没有值,则会进行插值,插值描述如下。
在域查询信息中,aggregator
是必要条款,但是可以通过none
来指明不做聚合运算。但是,TSDB多值模型不支持在同一个查询中有的域做聚合,有的域不做聚合。
插值
如果某条时间线某个精度区间没有值且没有使用fill policy
进行填值,而待聚合的其他时间线中有一条时间线在此精度区间有值,则会对本时间线的这个缺值精度区间进行插值。
例如:降采样以及聚合条件为{"downsample": "10s-avg", "aggregator": "10s-avg", "aggregator": "sum"}
,有两条时间线需要使用 sum聚合,按10s-avg
做降采样后的这两条时间线有值的时间戳分别为:
line 1:t+0,t+10,t+20,t+30、line 2:t+0,t+20,t+30。
第二条时间线 line 2 缺 “t+10” 这个时刻的值,那么在聚合前会对line 2的“t+10”这个时间点进行插值。插值的方法与聚合的算子有关,详见下面的算子列表。
算子 | 描述 | 插值方法 |
avg | 平均值 | 线性插值(斜率拟合) |
count | 数据点数 | 插 0 |
mimmin | 最小值 | 插最大值 |
mimmax | 最大值 | 插最小值 |
min | 最小值 | 线性插值 |
max | 最大值 | 线性插值 |
none | 不做计算 | 插 0 |
sum | 求和 | 线性插值 |
zimsum | 求和 | 插 0 |
Filters 说明
有以下两种方法可以指定filter:
在指定 tagk 时指定filter:
tagk = *:对tagk下面的tagv做分组,相同的tagv做聚合。
tagk = tagv1|tagv2:分别对tagk下面的tagv1和tagv2数据做聚合。
使用JSON格式指定filter:
名字 | 类型 | 是否必选 | 描述 | 默认值 | 举例 |
type | String | 是 | filter 类型,详见下面说明。 | 无 | literal_or |
tagk | String | 是 | 指定tagk名。 | 无 | host |
filter | String | 是 | filter表达式。 | 无 | web01丨web02 |
groupBy | Boolean | 否 | 是否按照tagv 做分组。 | false | false |
Filter 类型说明
名称 | filter 举例 | 描述 |
literal_or | web01丨web02 | 分别对多个tagv做聚合,区分大小写。 |
wildcard | *.example.com | 分别对满足通配符的tagv做聚合,区分大小写。 |
查询示例
包含 filter 的查询示例
请求体:
{
"start" : 1346846400,
"end" : 1346846411,
"msResolution" : true,
"queries" : [
{
"metric" : "wind",
"fields" : [
{
"field" : "speed",
"aggregator" : "none",
"alias" : "column_speed"
},
{
"field" : "*",
"aggregator" : "none",
"alias" : "column_"
}
],
"filters" : [
{
"filter" : "IOTE_8859_0005|IOTE_8859_0004",
"tagk" : "sensor",
"type" : "literal_or"
}
]
}
]
}
查询结果说明
查询成功的HTTP响应码为200,响应内容为JSON格式数据。说明如下:
名称 | 描述 |
metric | 指标名。 |
columns | 查询结果对应的列的名称。 |
tags | tagv未做聚合的tag。 |
aggregateTags | tagv做了聚合的tag。 |
values | Tuple结构查询结果。 |
响应结果示例:
Aggregator
:None
场景示例
[
{
"metric":"wind",
"columns":[
"timestamp",
"column_speed",
"column_description",
"column_direction",
"column_level",
"column_speed"
],
"tags":{
"city":"hangzhou",
"country":"china",
"province":"zhejiang",
"sensor":"IOTE_8859_0005"
},
"aggregatedTags":[],
"values":[
[ 1346846406000, null, "Fresh breeze", "East", 0.5, null ],
[ 1346846407000, null, "Fresh breeze", "South", 1.5, null ]
},
{
"metric":"wind",
"columns":[
"timestamp",
"column_speed",
"column_description",
"column_direction",
"column_level",
"column_speed"
],
"tags":{
"city":"hangzhou",
"country":"china",
"province":"zhejiang",
"sensor":"IOTE_8859_0004"
},
"aggregatedTags":[],
"values":[
[ 1346846400000, 40.4, "Fresh breeze", "East", 0.4, 40.4 ],
[ 1346846401000, 41.4, "Fresh breeze", "South", 1.4, 41.4 ],
[ 1346846402000, 42.4, "Fresh breeze", "West", 2.4, 42.4 ],
[ 1346846403000, 43.4, "Fresh breeze", "North", 3.4,43.4 ]
}
]
Aggregator
:Avg
的场景示例(查看杭州市所有sensor监控的平均风速和平均风等级)
[
{
"metric": "wind",
"columns": [
"timestamp",
"avg_level",
"avg_speed"
],
"tags": {
"city": "hangzhou"
},
"aggregatedTags": [
"country",
"province",
"sensor"
],
"values": [
[1346846400000, 0.25, 40.25],
[1346846401000, 1.25, 41.25],
[1346846402000, 2.5, 42.5],
[1346846411000, 5.5, null]
]
}
]
查询 Hint 化说明
场景说明
该特性主要是提高查询速度。假设某一个tags A命中的时间线明显大于其他的tags B命中的时间线,则需要舍弃,避免捞取tags A的大量时间线之后,被tags B小规模时间线交集后,结果集等于tags B。
格式说明
当前版本只支持tagk级别的查询索引限制(hint下的tagk是固定写法)。
其中,
0
表示不使用对应tagk的索引,反之1
表示使用对应tagk的索引。
版本说明
从v2.6.1版本开始支持hint特性。
查询示例
子查询级别
{
"queries": [
{
"metric": "demo.mf",
"tags": {
"sensor": "IOTE_8859_0001",
"city": "hangzhou",
"province": "zhejiang",
"country": "china"
},
"fields": [
"speed"
],
"hint": {
"tagk": {
"dc": 1
}
}
}
]
}
整体查询级别
{
"queries": [
{
"metric": "demo.mf",
"tags": {
"sensor": "IOTE_8859_0001",
"city": "hangzhou",
"province": "zhejiang",
"country": "china"
},
"fields": [
"speed"
]
}
],
"hint": {
"tagk": {
"dc": 1
}
}
}
异常情况
不可同时指定 0 和 1
{
"start": 1346846400,
"end": 1346846400,
"queries": [
{
"aggregator": "none",
"metric": "sys.cpu.nice",
"tags": {
"dc": "lga",
"host": "web01"
}
}
],
"hint": {
"tagk": {
"dc": 1,
"host": 0
}
}
}
会返回如下报错信息:
{
"error": {
"code": 400,
"message": "The value of hint should only be 0 or 1, and there should not be both 0 and 1",
"details": "TSQuery(start_time=1346846400, end_time=1346846400, subQueries[TSSubQuery(metric=sys.cpu.nice, filters=[filter_name=literal_or, tagk=dc, literals=[lga], group_by=true, filter_name=literal_or, tagk=host, literals=[web01], group_by=true], tsuids=[], agg=none, downsample=null, ds_interval=0, rate=false, rate_options=null, delta=false, delta_options=null, top=0, granularity=null, granularityDownsample=null, explicit_tags=explicit_tags, index=0, realTimeSeconds=-1, useData=auto, limit=0, offset=0, dpValue=null, preDpValue=null, startTime=1346846400000, endTime=1346846400000, Query_ID=null)] padding=false, no_annotations=false, with_global_annotations=false, show_tsuids=false, ms_resolution=false, options=[])"
}
}
不可指定除了 0 和 1 之外的值
{
"start": 1346846400,
"end": 1346846400,
"queries": [
{
"aggregator": "none",
"metric": "sys.cpu.nice",
"tags": {
"dc": "lga",
"host": "web01"
}
}
],
"hint": {
"tagk": {
"dc": 100
}
}
}
会返回如下报错信息:
{
"error": {
"code": 400,
"message": "The value of hint can only be 0 or 1, and it is detected that '100' is passed in",
"details": "TSQuery(start_time=1346846400, end_time=1346846400, subQueries[TSSubQuery(metric=sys.cpu.nice, filters=[filter_name=literal_or, tagk=dc, literals=[lga], group_by=true, filter_name=literal_or, tagk=host, literals=[web01], group_by=true], tsuids=[], agg=none, downsample=null, ds_interval=0, rate=false, rate_options=null, delta=false, delta_options=null, top=0, granularity=null, granularityDownsample=null, explicit_tags=explicit_tags, index=0, realTimeSeconds=-1, useData=auto, limit=0, offset=0, dpValue=null, preDpValue=null, startTime=1346846400000, endTime=1346846400000, Query_ID=null)] padding=false, no_annotations=false, with_global_annotations=false, show_tsuids=false, ms_resolution=false, options=[])"
}
}