druid 查詢介面的使用

Xlucas發表於2017-09-01

核心
druid 查詢介面的使用

druid的查詢介面是HTTP REST 風格的查詢方式,使用HTTP REST 風格查詢(Broker,Historical,或者Realtime)節點的資料,查詢引數為JSON格式,每個節點型別都會暴露相同的REST查詢介面

curl -X POST '<queryable_host>:<port>/druid/v2/?pretty' -H 'Content-Type:application/json' -d @<query_json_file>

queryable_host: broker節點ip port: broker 節點埠 預設是8082

curl -L -H'Content-Type: application/json' -XPOST --data-binary @quickstart/aa.json http://10.20.23.41:8082/druid/v2/?pretty

query 查詢的型別有
1、Timeseries
2、TopN
3、GroupBy
4、Time Boundary
5、Segment Metadata
6、Datasource Metadata
7、Search
8、select

其中 Timeseries、TopN、GroupBy為聚合查詢,Time Boundary、Segment Metadata、Datasource Metadata 為後設資料查詢,Search 為搜尋查詢

1、Timeseries
對於需要統計一段時間內的彙總資料,或者是指定時間粒度的彙總資料,druid可以通過Timeseries來完成。

timeseries 查詢包括如下的欄位

欄位名            描述                             是否必須
queryType      查詢型別,這裡只有填寫timeseries查詢     是
dataSource       要查詢的資料集                       是
descending          是否降序                           否
intervals    查詢的時間範圍,預設是ISO-8601格式         是
granularity   查詢結果進行聚合的時間粒度            是
filter                過濾條件                     否
aggregations         聚合                         是      
postAggregations    後期聚合                            否
context             指定一些查詢引數                    否

timeseries輸出每個時間粒度內指定條件的統計資訊,通過filter指定條件過濾,通過aggregations和postAggregations指定聚合方式。timeseries不能輸出維度資訊,granularity支援all,none,second,minute,hour,day,week,month,year等維度

all:彙總1條輸出 none:不推薦使用

其他的:則輸出相應粒度統計資訊

查詢的json

{
  "aggregations": [
    {
      "type": "count", 
      "name": "count"
    }
  ], 
  "intervals": "1917-08-25T08:35:20+00:00/2017-08-25T08:35:20+00:00", 
  "dataSource": "app_auto_prem_qd_pp3", 
  "granularity": "all", 
  "postAggregations": [], 
  "queryType": "timeseries"
}

等同於sql select count(1) from app_auto_prem_qd_pp3

TopN
返回指定維度和排序欄位的有序top-n序列.TopN支援返回前N條記錄,並支援指定的Metric為排序依據

{
  "metric": "sum__total_standard_premium", 
  "aggregations": [
    {
      "type": "doubleSum", 
      "fieldName": "total_standard_premium", 
      "name": "sum__total_standard_premium"
    }
  ], 
  "dimension": "is_new_car", 
  "intervals": "1917-08-29T20:05:10+00:00/2017-08-29T20:05:10+00:00", 
  "dataSource": "app_auto_prem_qd_pp3", 
  "granularity": "all", 
  "threshold": 50000, 
  "postAggregations": [], 
  "queryType": "topN"
}
欄位名            描述                             是否必須
queryType     對於TopN查詢,這個必須是TopN              是
dataSource       要查詢的資料集                         是
intervals    查詢的時間範圍,預設是ISO-8601格式           是
filter                過濾條件                       否
aggregations           聚合                       是
postAggregations      後期聚合                      否
dimension   進行TopN查詢的維護,一個TopN查詢只能有一個維度  是
threshold          TopN中的N值                        是
metric               進行統計並排序的metric             是
context             指定一些查詢引數                    否

metric:是TopN專屬
方式:

"metric":"<metric_name>" 預設情況是升序排序的

"metric" : {
    "type" : "numeric", //指定按照numeric 降序排序
    "metric" : "<metric_name>"
}

"metric" : {
    "type" : "inverted", //指定按照numeric 升序排序
    "metric" : "<metric_name>"
}

"metric" : {
    "type" : "lexicographic", //指定按照字典序排序
    "metric" : "<metric_name>"
}

"metric" : {
    "type" : "alphaNumeric", //指定按照數字排序
    "metric" : "<metric_name>"
}

需要注意的是,TopN是一個近似演算法,每一個segment返回前1000條進行合併得到最後的結果,如果dimension
的基數在1000以內,則是準確的,超過1000就是近似值

groupBy
groupBy 類似於SQL中的group by 操作,能對指定的多個維度進行分組,也支援對指定的維度進行排序,並輸出limit行數,同時支援having操作

{
  "dimensions": [
    "is_new_car", 
    "status"
  ], 
  "aggregations": [
    {
      "type": "doubleSum", 
      "fieldName": "total_standard_premium", 
      "name": "sum__total_standard_premium"
    }
  ], 
  "having": {
    "type": "greaterThan", 
    "aggregation": "sum__total_standard_premium", 
    "value": "484000"
  }, 
  "intervals": "1917-08-29T20:26:52+00:00/2017-08-29T20:26:52+00:00", 
  "limitSpec": {
    "limit": 2, 
    "type": "default", 
    "columns": [
      {
        "direction": "descending", 
        "dimension": "sum__total_standard_premium"
      }
    ]
  }, 
  "granularity": "all", 
  "postAggregations": [], 
  "queryType": "groupBy", 
  "dataSource": "app_auto_prem_qd_pp3"
}

等同於sql select is_new_car,status,sum(total_standard_premium) from app_auto_prem_qd_pp3 group by is_new_car,status limit 50000 having sum(total_standard_premium)>484000

{
  "version" : "v1",
  "timestamp" : "1917-08-30T04:26:52.000+08:00",
  "event" : {
    "sum__total_standard_premium" : 8.726074368E9,
    "is_new_car" : "是",
    "status" : null
  }
}, {
  "version" : "v1",
  "timestamp" : "1917-08-30T04:26:52.000+08:00",
  "event" : {
    "sum__total_standard_premium" : 615152.0,
    "is_new_car" : "否",
    "status" : null
  }
  }
欄位名            描述                             是否必須
queryType      對於GroupBy查詢,該欄位必須是GroupBy     是
dataSource          要查詢的資料集                     是
dimensions      進行GroupBy查詢的維度集合               是
limitSpec           統計結果進行排序                    否
having             對統計結果進行篩選                    否
granularity            查詢結果進行聚合的時間粒度         是 
postAggregations        後聚合器                       否
intervals        查詢的時間範圍,預設是ISO-8601格式        是
context             指定一些查詢引數                    否

GroupBy特有的欄位為limitSpec 和having

limitSpec
指定排序規則和limit的行數

{
    "type" : "default",
    "limit":<integer_value>,
    "columns":[list of OrderByColumnSpec]
}

其中columns是一個陣列,可以指定多個排序欄位,排序欄位可以使demension 或者metric 指定排序規則的拼寫方式

{
    "dimension" :"<Any dimension or metric name>",  
    "direction" : <"ascending"|"descending">
}

 "limitSpec": {
    "limit": 2, 
    "type": "default", 
    "columns": [
      {
        "direction": "descending", 
        "dimension": "sum__total_standard_premium"
      },
     {
        "direction": "ascending", 
        "dimension": "is_new_car"
      } 
    ]
  }

having 類似於SQL中的having操作

select

select 類似於sql中select操作,select用來檢視druid中的儲存的資料,並支援按照指定過濾器和時間段檢視指定維度和metric,能通過descending欄位指定排序順序,並支援分頁拉取,但不支援aggregations和postAggregations
json 例項如下

{
  "dimensions": [
      "status",
      "is_new_car"
  ], 
  "pagingSpec":{
  "pagingIdentifiers":{},
  "threshold":3
  },
  "intervals": "1917-08-25T08:35:20+00:00/2017-08-25T08:35:20+00:00", 
  "dataSource": "app_auto_prem_qd_pp3", 
  "granularity": "all", 
  "context" : {
   "skipEmptyBuckets" : "true"
  },
  "queryType": "select"
}

相當於SQL語句 select status,is_new_car from app_auto_prem_qd_pp3 limit 3

[ {
  "timestamp" : "2017-08-22T14:00:00.000Z",
  "result" : {
    "pagingIdentifiers" : {
      "app_auto_prem_qd_pp3_2017-08-22T08:00:00.000+08:00_2017-08-23T08:00:00.000+08:00_2017-08-22T18:11:01.983+08:00" : 2
    },
    "dimensions" : [ "is_new_car", "status" ],
    "metrics" : [ "total_actual_premium", "count", "total_standard_premium" ],
    "events" : [ {
      "segmentId" : "app_auto_prem_qd_pp3_2017-08-22T08:00:00.000+08:00_2017-08-23T08:00:00.000+08:00_2017-08-22T18:11:01.983+08:00",
      "offset" : 0,
      "event" : {
        "timestamp" : "2017-08-22T22:00:00.000+08:00",
        "status" : null,
        "is_new_car" : "是",
        "total_actual_premium" : 1012.5399780273438,
        "count" : 1,
        "total_standard_premium" : 1250.050048828125
      }
    }, {
      "segmentId" : "app_auto_prem_qd_pp3_2017-08-22T08:00:00.000+08:00_2017-08-23T08:00:00.000+08:00_2017-08-22T18:11:01.983+08:00",
      "offset" : 1,
      "event" : {
        "timestamp" : "2017-08-22T22:00:00.000+08:00",
        "status" : null,
        "is_new_car" : "是",
        "total_actual_premium" : 708.780029296875,
        "count" : 1,
        "total_standard_premium" : 1250.050048828125
      }
    }, {
      "segmentId" : "app_auto_prem_qd_pp3_2017-08-22T08:00:00.000+08:00_2017-08-23T08:00:00.000+08:00_2017-08-22T18:11:01.983+08:00",
      "offset" : 2,
      "event" : {
        "timestamp" : "2017-08-22T22:00:00.000+08:00",
        "status" : null,
        "is_new_car" : "是",
        "total_actual_premium" : 1165.489990234375,
        "count" : 1,
        "total_standard_premium" : 1692.800048828125
      }
    } ]
  }
} ]

在pagingSpec中指定分頁拉取的offset和條目數,在結果中會返回下次拉取的offset,

 "pagingSpec":{
  "pagingIdentifiers":{},
  "threshold":3,
  "fromNext" :true
  }

Search

search 查詢返回匹配中的維度,類似於SQL中的topN操作,但是支援更多的匹配操作,
json示例如

{
  "queryType": "search",
  "dataSource": "app_auto_prem_qd_pp3",
  "granularity": "all",
  "limit": 2,
  "searchDimensions": [
    "data_source",
    "department_code"
  ],
  "query": {
    "type": "insensitive_contains",
    "value": "1"
  },
  "sort" : {
    "type": "lexicographic"
  },
  "intervals": [
    "1917-08-25T08:35:20+00:00/2017-08-25T08:35:20+00:00"
  ]
} 

searchDimensions搜尋的維度

欄位名            描述                             是否必須
queryType         對於search查詢,該欄位必須是search    是
dataSource            要查詢的資料集                  是
searchDimensions     執行search的維度                 是
limit               對統計結果進行限制             否(預設1000)
granularity        查詢結果進行聚合的時間粒度         是 
intervals           查詢的時間範圍,預設是ISO-8601格式   是
sort                  指定搜尋結果排序                  否
query               查詢操作                          是
context              指定一些查詢引數                   否
filter                 過濾器                        否

需要注意的是,search只是返回匹配中維度,不支援其他聚合操作,如果要將search作為查詢條件進行topN,groupBy或timeseries等操作,則可以在filter欄位中
指定各種過濾方式,filter欄位也支援正則匹配,
查詢結果如下:

[ {
  "timestamp" : "2017-08-22T08:00:00.000+08:00",
  "result" : [ {
    "dimension" : "data_source",
    "value" : "226931204023",
    "count" : 2
  }, {
    "dimension" : "data_source",
    "value" : "226931204055",
    "count" : 7
  } ]
} ]

查詢的選擇

1、在可能的情況下,建議使用Timeseries和TopN查詢而不是GroupBy,GroupBy是最靈活的查詢,也是最差的表現。對於不需要對維度進行分組的聚合,Timeseries比GroupBy查詢要快,對於單個維度進行分組和排序,TopN查詢比GroupBy更加優化

相關文章