JSON 쿼리
JSON 쿼리 (JSON querying) API
Apache Druid에 JSON 기반 네이티브 쿼리를 제출하는 API 엔드포인트를 다룹니다. 쿼리 제출 방법과 쿼리별 서버 위치 조회 방법을 설명해요.
출처: 문서
본문
이 문서는 Apache Druid에 JSON 기반 네이티브 쿼리(native query)를 제출하는 API 엔드포인트를 설명합니다.
이 문서에서 http://SERVICE_IP:SERVICE_PORT는 배포의 서버 주소와 서비스 포트를 위한 자리표시자입니다. 예를 들어 quickstart 구성에서 http://ROUTER_IP:ROUTER_PORT를 http://localhost:8888로 교체하세요.
쿼리 제출
JSON 기반 네이티브 쿼리를 제출합니다. 요청 본문이 바로 네이티브 쿼리입니다.
Druid는 다양한 유스케이스를 위해 여러 타입의 쿼리를 지원합니다. 모든 쿼리는 다음 속성을 요구합니다.
- queryType: 쿼리 타입을 나타내는 문자열. Druid는 다음 네이티브 쿼리 타입을 지원합니다:
timeseries,topN,groupBy,timeBoundaries,segmentMetadata,datasourceMetadata,scan,search. - dataSource: 쿼리할 데이터의 소스를 정의하는 문자열 또는 객체. 가장 흔한 값은 쿼리할 데이터소스의 이름입니다. 자세한 내용은 Datasources를 참고하세요.
쿼리 타입이나 유스케이스에 따른 추가 속성은 available native queries를 참고하세요.
URL
POST /druid/v2
쿼리 파라미터
- pretty (선택) — Druid가 들여쓰기와 줄바꿈을 사용해 응답을 pretty-printed 형식으로 반환합니다.
응답
- 200 SUCCESS — 쿼리를 성공적으로 제출함
- 400 BAD REQUEST — 잘못된 쿼리로 인한 오류. 다음 형식의 오류를 자세히 설명하는 JSON 객체를 반환합니다.
{
"error": "A well-defined error code.",
"errorMessage": "A message with additional details about the error.",
"errorClass": "Class of exception that caused this error.",
"host": "The host on which the error occurred."
}
가능한 오류 메시지에 대한 자세한 내용은 query execution failures를 참고하세요.
예제 쿼리: topN
다음 예시는 topN 쿼리를 보여줍니다. 이 쿼리는 social_media 데이터소스를 분석해 views 메트릭에서 가장 많은 뷰 수를 가진 username 차원의 상위 5명의 사용자를 반환합니다.
cURL
curl "http://ROUTER_IP:ROUTER_PORT/druid/v2?pretty=null" \
--header 'Content-Type: application/json' \
--data '{
"queryType": "topN",
"dataSource": "social_media",
"dimension": "username",
"threshold": 5,
"metric": "views",
"granularity": "all",
"aggregations": [
{
"type": "longSum",
"name": "views",
"fieldName": "views"
}
],
"intervals": [
"2022-01-01T00:00:00.000/2024-01-01T00:00:00.000"
]
}'
HTTP
POST /druid/v2?pretty=null HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT
Content-Type: application/json
Content-Length: 336
{
"queryType": "topN",
"dataSource": "social_media",
"dimension": "username",
"threshold": 5,
"metric": "views",
"granularity": "all",
"aggregations": [
{
"type": "longSum",
"name": "views",
"fieldName": "views"
}
],
"intervals": [
"2022-01-01T00:00:00.000/2024-01-01T00:00:00.000"
]
}
예제 응답: topN
[
{
"timestamp": "2023-07-03T18:49:54.848Z",
"result": [
{
"views": 11591218026,
"username": "gus"
},
{
"views": 11578638578,
"username": "miette"
},
{
"views": 11561618880,
"username": "leon"
},
{
"views": 11552609824,
"username": "mia"
},
{
"views": 11551537517,
"username": "milton"
}
]
}
]
예제 쿼리: groupBy
다음 예시는 social_media 데이터소스에서 게시물 대비 투표 비율이 가장 높은 사용자를 가져오기 위해 groupBy 타입의 JSON 쿼리를 제출합니다.
이 쿼리에서:
upvoteSum집계는 각 사용자의 투표 합계를 계산합니다.postCount집계는 각 사용자의 게시물 합계를 계산합니다.upvoteToPostRatio는upvoteSum과postCount를 나눠 비율을 계산하는 post-aggregation입니다.- 결과는
upvoteToPostRatio를 기준으로 내림차순 정렬됩니다.
cURL
curl "http://ROUTER_IP:ROUTER_PORT/druid/v2" \
--header 'Content-Type: application/json' \
--data '{
"queryType": "groupBy",
"dataSource": "social_media",
"dimensions": ["username"],
"granularity": "all",
"aggregations": [
{ "type": "doubleSum", "name": "upvoteSum", "fieldName": "upvotes" },
{ "type": "count", "name": "postCount", "fieldName": "post_title" }
],
"postAggregations": [
{
"type": "arithmetic",
"name": "upvoteToPostRatio",
"fn": "/",
"fields": [
{ "type": "fieldAccess", "name": "upvoteSum", "fieldName": "upvoteSum" },
{ "type": "fieldAccess", "name": "postCount", "fieldName": "postCount" }
]
}
],
"intervals": ["2022-01-01T00:00:00.000/2024-01-01T00:00:00.000"],
"limitSpec": {
"type": "default",
"limit": 1,
"columns": [
{ "dimension": "upvoteToPostRatio", "direction": "descending" }
]
}
}'
HTTP
POST /druid/v2?pretty=null HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT
Content-Type: application/json
Content-Length: 817
{
"queryType": "groupBy",
"dataSource": "social_media",
"dimensions": ["username"],
"granularity": "all",
"aggregations": [
{ "type": "doubleSum", "name": "upvoteSum", "fieldName": "upvotes" },
{ "type": "count", "name": "postCount", "fieldName": "post_title" }
],
"postAggregations": [
{
"type": "arithmetic",
"name": "upvoteToPostRatio",
"fn": "/",
"fields": [
{ "type": "fieldAccess", "name": "upvoteSum", "fieldName": "upvoteSum" },
{ "type": "fieldAccess", "name": "postCount", "fieldName": "postCount" }
]
}
],
"intervals": ["2022-01-01T00:00:00.000/2024-01-01T00:00:00.000"],
"limitSpec": {
"type": "default",
"limit": 1,
"columns": [
{ "dimension": "upvoteToPostRatio", "direction": "descending" }
]
}
}
예제 응답: groupBy
[
{
"version": "v1",
"timestamp": "2022-01-01T00:00:00.000Z",
"event": {
"upvoteSum": 8.0419541E7,
"upvoteToPostRatio": 69.53014661762697,
"postCount": 1156614,
"username": "miette"
}
}
]
쿼리에 대한 세그먼트 정보 가져오기
요청 본문에 제공된 쿼리와 연관된 서버 위치를 포함해 세그먼트 정보가 담긴 객체를 가진 배열을 가져옵니다.
URL
POST /druid/v2/candidates
쿼리 파라미터
- pretty (선택) — Druid가 들여쓰기와 줄바꿈을 사용해 응답을 pretty-printed 형식으로 반환합니다.
응답
- 200 SUCCESS — 세그먼트 정보를 성공적으로 조회함
- 400 BAD REQUEST — 잘못된 쿼리로 인한 오류. 다음 형식의 오류를 자세히 설명하는 JSON 객체를 반환합니다.
{
"error": "A well-defined error code.",
"errorMessage": "A message with additional details about the error.",
"errorClass": "Class of exception that caused this error.",
"host": "The host on which the error occurred."
}
가능한 오류 메시지에 대한 자세한 내용은 query execution failures를 참고하세요.
샘플 요청
cURL
curl "http://ROUTER_IP:ROUTER_PORT/druid/v2/candidates" \
--header 'Content-Type: application/json' \
--data '{
"queryType": "topN",
"dataSource": "social_media",
"dimension": "username",
"threshold": 5,
"metric": "views",
"granularity": "all",
"aggregations": [
{
"type": "longSum",
"name": "views",
"fieldName": "views"
}
],
"intervals": [
"2022-01-01T00:00:00.000/2024-01-01T00:00:00.000"
]
}'
HTTP
POST /druid/v2/candidates HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT
Content-Type: application/json
Content-Length: 336
{
"queryType": "topN",
"dataSource": "social_media",
"dimension": "username",
"threshold": 5,
"metric": "views",
"granularity": "all",
"aggregations": [
{
"type": "longSum",
"name": "views",
"fieldName": "views"
}
],
"intervals": [
"2020-01-01T00:00:00.000/2024-01-01T00:00:00.000"
]
}
샘플 응답
[
{
"interval": "2023-07-03T18:00:00.000Z/2023-07-03T19:00:00.000Z",
"version": "2023-07-03T18:51:18.905Z",
"partitionNumber": 0,
"size": 21563693,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-03T19:00:00.000Z/2023-07-03T20:00:00.000Z",
"version": "2023-07-03T19:00:00.657Z",
"partitionNumber": 0,
"size": 6057236,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-05T21:00:00.000Z/2023-07-05T22:00:00.000Z",
"version": "2023-07-05T21:09:58.102Z",
"partitionNumber": 0,
"size": 223926186,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-05T21:00:00.000Z/2023-07-05T22:00:00.000Z",
"version": "2023-07-05T21:09:58.102Z",
"partitionNumber": 1,
"size": 20244827,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-05T22:00:00.000Z/2023-07-05T23:00:00.000Z",
"version": "2023-07-05T22:00:00.524Z",
"partitionNumber": 0,
"size": 104628051,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-05T22:00:00.000Z/2023-07-05T23:00:00.000Z",
"version": "2023-07-05T22:00:00.524Z",
"partitionNumber": 1,
"size": 1603995,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-05T23:00:00.000Z/2023-07-06T00:00:00.000Z",
"version": "2023-07-05T23:21:55.242Z",
"partitionNumber": 0,
"size": 181506843,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T00:00:00.000Z/2023-07-06T01:00:00.000Z",
"version": "2023-07-06T00:02:08.498Z",
"partitionNumber": 0,
"size": 9170974,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T00:00:00.000Z/2023-07-06T01:00:00.000Z",
"version": "2023-07-06T00:02:08.498Z",
"partitionNumber": 1,
"size": 23969632,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T01:00:00.000Z/2023-07-06T02:00:00.000Z",
"version": "2023-07-06T01:13:53.982Z",
"partitionNumber": 0,
"size": 599895,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T01:00:00.000Z/2023-07-06T02:00:00.000Z",
"version": "2023-07-06T01:13:53.982Z",
"partitionNumber": 1,
"size": 1627041,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T02:00:00.000Z/2023-07-06T03:00:00.000Z",
"version": "2023-07-06T02:55:50.701Z",
"partitionNumber": 0,
"size": 629753,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T02:00:00.000Z/2023-07-06T03:00:00.000Z",
"version": "2023-07-06T02:55:50.701Z",
"partitionNumber": 1,
"size": 1342360,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T04:00:00.000Z/2023-07-06T05:00:00.000Z",
"version": "2023-07-06T04:02:36.562Z",
"partitionNumber": 0,
"size": 2131434,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T05:00:00.000Z/2023-07-06T06:00:00.000Z",
"version": "2023-07-06T05:23:27.856Z",
"partitionNumber": 0,
"size": 797161,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T05:00:00.000Z/2023-07-06T06:00:00.000Z",
"version": "2023-07-06T05:23:27.856Z",
"partitionNumber": 1,
"size": 1176858,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T06:00:00.000Z/2023-07-06T07:00:00.000Z",
"version": "2023-07-06T06:46:34.638Z",
"partitionNumber": 0,
"size": 2148760,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T07:00:00.000Z/2023-07-06T08:00:00.000Z",
"version": "2023-07-06T07:38:28.050Z",
"partitionNumber": 0,
"size": 2040748,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T08:00:00.000Z/2023-07-06T09:00:00.000Z",
"version": "2023-07-06T08:27:31.407Z",
"partitionNumber": 0,
"size": 678723,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T08:00:00.000Z/2023-07-06T09:00:00.000Z",
"version": "2023-07-06T08:27:31.407Z",
"partitionNumber": 1,
"size": 1437866,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T10:00:00.000Z/2023-07-06T11:00:00.000Z",
"version": "2023-07-06T10:02:42.079Z",
"partitionNumber": 0,
"size": 1671296,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T11:00:00.000Z/2023-07-06T12:00:00.000Z",
"version": "2023-07-06T11:27:23.902Z",
"partitionNumber": 0,
"size": 574893,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T11:00:00.000Z/2023-07-06T12:00:00.000Z",
"version": "2023-07-06T11:27:23.902Z",
"partitionNumber": 1,
"size": 1427384,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T12:00:00.000Z/2023-07-06T13:00:00.000Z",
"version": "2023-07-06T12:52:00.846Z",
"partitionNumber": 0,
"size": 2115172,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T14:00:00.000Z/2023-07-06T15:00:00.000Z",
"version": "2023-07-06T14:32:33.926Z",
"partitionNumber": 0,
"size": 589108,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T14:00:00.000Z/2023-07-06T15:00:00.000Z",
"version": "2023-07-06T14:32:33.926Z",
"partitionNumber": 1,
"size": 1392649,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T15:00:00.000Z/2023-07-06T16:00:00.000Z",
"version": "2023-07-06T15:53:25.467Z",
"partitionNumber": 0,
"size": 2037851,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T16:00:00.000Z/2023-07-06T17:00:00.000Z",
"version": "2023-07-06T16:02:26.568Z",
"partitionNumber": 0,
"size": 230400650,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T16:00:00.000Z/2023-07-06T17:00:00.000Z",
"version": "2023-07-06T16:02:26.568Z",
"partitionNumber": 1,
"size": 38209056,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
},
{
"interval": "2023-07-06T17:00:00.000Z/2023-07-06T18:00:00.000Z",
"version": "2023-07-06T17:00:02.391Z",
"partitionNumber": 0,
"size": 211099463,
"locations": [
{
"name": "localhost:8083",
"host": "localhost:8083",
"hostAndTlsPort": null,
"maxSize": 300000000000,
"type": "historical",
"tier": "_default_tier",
"priority": 0
}
]
}
]
더 알아보기 (Learn more)
- 네이티브 쿼리 타입의 전체 목록은 native queries 문서를 참고하세요.
- SQL을 사용하고 싶다면 Druid SQL 문서를 확인해 보세요.