SQL and PPL API
SQL and PPL API
SQL and PPL API를 사용해 SQL 플러그인에 질의를 보내요. SQL 질의를 보내려면 _sql 엔드포인트를, PPL 질의를 보내려면 _ppl 엔드포인트를 사용해요. 두 경우 모두 _explain 엔드포인트를 사용해 질의를 OpenSearch 도메인 특화 언어(DSL)로 변환하거나 오류를 진단할 수 있어요.
출처: 문서
본문
Query API
SQL/PPL 질의를 SQL 플러그인에 보내요. 응답 형식을 질의 파라미터로 전달할 수 있어요.
질의 파라미터 (Query parameters)
| Parameter | Data type | Description |
|---|---|---|
| format | String | 응답 형식이에요. _sql 엔드포인트는 jdbc, csv, raw, json 형식을 지원하고, _ppl 엔드포인트는 jdbc, csv, raw 형식을 지원해요. 기본값은 jdbc예요. |
sanitize |
Boolean | 결과에서 특수 문자를 이스케이프할지 여부를 지정해요. 자세한 내용은 Response formats를 참고하세요. 기본값은 true예요. |
요청 본문 필드 (Request body fields)
| Field | Data type | Description |
|---|---|---|
query |
String | 실행할 질의예요. 필수예요. |
| filter | JSON object | 결과에 대한 필터예요. 선택 사항이에요. |
| fetch_size | integer | 한 응답에서 반환할 결과 수예요. 결과 페이지네이션에 사용돼요. 기본값은 1,000이에요. 선택 사항이에요. fetch_size는 SQL에서 지원되며 jdbc 응답 형식을 사용해야 해요. |
예시 요청
POST /_plugins/_sql
{
"query" : "SELECT * FROM accounts"
}
예시 응답
응답에는 스키마와 결과가 포함돼요.
{
"schema": [
{
"name": "account_number",
"type": "long"
},
{
"name": "firstname",
"type": "text"
},
{
"name": "address",
"type": "text"
},
{
"name": "balance",
"type": "long"
},
{
"name": "gender",
"type": "text"
},
{
"name": "city",
"type": "text"
},
{
"name": "employer",
"type": "text"
},
{
"name": "state",
"type": "text"
},
{
"name": "age",
"type": "long"
},
{
"name": "email",
"type": "text"
},
{
"name": "lastname",
"type": "text"
}
],
"datarows": [
[
1,
"Amber",
"880 Holmes Lane",
39225,
"M",
"Brogan",
"Pyrami",
"IL",
32,
"[email protected]",
"Duke"
],
[
6,
"Hattie",
"671 Bristol Street",
5686,
"M",
"Dante",
"Netagy",
"TN",
36,
"[email protected]",
"Bond"
],
[
13,
"Nanette",
"789 Madison Street",
32838,
"F",
"Nogal",
"Quility",
"VA",
28,
"[email protected]",
"Bates"
],
[
18,
"Dale",
"467 Hutchinson Court",
4180,
"M",
"Orick",
null,
"MD",
33,
"[email protected]",
"Adams"
]
],
"total": 4,
"size": 4,
"status": 200
}
응답 본문 필드 (Response body fields)
| Field | Data type | Description |
|---|---|---|
schema |
Array | 모든 필드의 필드 이름과 타입을 지정해요. |
data_rows |
Two-dimensional array | 결과 배열이에요. 각 결과는 하나의 일치하는 행(문서)을 나타내요. |
total |
Integer | 인덱스의 총 행(문서) 수예요. |
size |
Integer | 한 응답에서 반환할 결과 수예요. |
status |
String | 질의를 실행한 후 OpenSearch가 반환하는 HTTP 응답 상태예요. |
Explain API
SQL 플러그인의 explain 기능은 질의가 OpenSearch에 대해 어떻게 실행되는지 보여줘서 디버깅과 개발에 유용해요. _plugins/_sql/_explain 또는 _plugins/_ppl/_explain 엔드포인트에 POST 요청을 보내면 OpenSearch 도메인 특화 언어(DSL)가 JSON 형식으로 반환돼요.
OpenSearch 3.0.0부터 plugins.calcite.enabled를 true로 설정하면 explain 응답이 질의 실행 계획에 대한 향상된 정보를 제공해요. 이 API는 네 가지 출력 형식을 지원해요.
standard: 논리 및 물리 계획을 표시해요(지정하지 않으면 기본값)simple: 속성 없이 논리 계획을 표시해요cost: 비용과 함께 논리 및 물리 계획을 표시해요extended: 생성된 코드와 함께 논리 및 물리 계획을 표시해요
예시 (Examples)
다음 예시들은 다양한 explain 질의를 보여줘요.
기본 SQL 질의
다음 요청은 기본 SQL explain 질의를 보여줘요.
POST _plugins/_sql/_explain
{
"query": "SELECT firstname, lastname FROM accounts WHERE age > 20"
}
응답은 질의 실행 계획을 보여줘요.
{
"root": {
"name": "ProjectOperator",
"description": {
"fields": "[firstname, lastname]"
},
"children": [
{
"name": "OpenSearchIndexScan",
"description": {
"request": "\"\"\"OpenSearchQueryRequest(indexName=accounts, sourceBuilder={\"from\":0,\"size\":200,\"timeout\":\"1m\",\"query\":{\"range\":{\"age\":{\"from\":20,\"to\":null,\"include_lower\":false,\"include_upper\":true,\"boost\":1.0}}},\"_source\":{\"includes\":[\"firstname\",\"lastname\"],\"excludes\":[]},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}]}, searchDone=false)\"\"\""
},
"children": []
}
]
}
}
Calcite 엔진을 사용한 고급 질의
다음 요청은 Calcite 엔진을 사용하는 더 복잡한 질의를 보여줘요.
POST _plugins/_ppl/_explain
{
"query" : "source=state_country | where country = 'USA' OR country = 'England' | stats count() by country"
}
응답은 표준 형식으로 논리 및 물리 계획을 모두 보여줘요.
{
"calcite": {
"logical": "\"\"\"LogicalProject(count()=[$1], country=[$0])
LogicalAggregate(group=[{1}], count()=[COUNT()])
LogicalFilter(condition=[SEARCH($1, Sarg['England', 'USA':CHAR(7)]:CHAR(7))])
CalciteLogicalIndexScan(table=[[OpenSearch, state_country]])
\"\"\",
"physical": "\"\"\"EnumerableCalc(expr#0..1=[{inputs}], count()=[$t1], country=[$t0])
CalciteEnumerableIndexScan(table=[[OpenSearch, state_country]], PushDownContext=[[FILTER->SEARCH($1, Sarg['England', 'USA':CHAR(7)]:CHAR(7)), AGGREGATION->rel#53:LogicalAggregate.NONE.[](input=RelSubset#43,group={1},count()=COUNT())], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":0,\"timeout\":\"1m\",\"query\":{\"terms\":{\"country\":[\"England\",\"USA\"],\"boost\":1.0}},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}],\"aggregations\":{\"composite_buckets\":{\"composite\":{\"size\":1000,\"sources\":[{\"country\":{\"terms\":{\"field\":\"country\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}}]},\"aggregations\":{\"count()\":{\"value_count\":{\"field\":\"_index\"}}}}}}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
\"\"\"
}
}
질의 계획을 단순하게 보려면 simple 형식을 사용할 수 있어요.
POST _plugins/_ppl/_explain?format=simple
{
"query" : "source=state_country | where country = 'USA' OR country = 'England' | stats count() by country"
}
응답은 간결한 논리 계획을 보여줘요.
{
"calcite": {
"logical": "\"\"\"LogicalProject
LogicalAggregate
LogicalFilter
CalciteLogicalIndexScan
\"\"\"
}
}
후처리가 필요한 질의의 경우 explain 응답은 OpenSearch DSL과 함께 질의 계획을 포함해요. 후처리가 필요 없는 질의의 경우 완전한 DSL만 볼 수 있어요.
결과 페이지네이션 (Paginating results)
페이지네이션된 응답을 받으려면 fetch_size 파라미터를 사용하세요. fetch_size의 값은 0보다 커야 해요. 기본값은 1,000이에요. 값이 0이면 페이지네이션되지 않은 응답으로 폴백해요.
fetch_size 파라미터는 jdbc 응답 형식에서만 지원돼요.
예시
다음 요청은 SQL 질의를 포함하고 한 번에 5개의 결과를 반환하도록 지정해요.
POST _plugins/_sql/
{
"fetch_size" : 5,
"query" : "SELECT firstname, lastname FROM accounts WHERE age > 20 ORDER BY state ASC"
}
응답에는 fetch_size가 없는 질의가 담는 모든 필드와 함께, 이후 결과 페이지를 가져오는 데 사용되는 cursor 필드가 포함돼요.
{
"schema": [
{
"name": "firstname",
"type": "text"
},
{
"name": "lastname",
"type": "text"
}
],
"cursor": "d:eyJhIj...NTF9",
"total": 956,
"datarows": [
[
"Cherry",
"Carey"
],
[
"Lindsey",
"Hawkins"
],
[
"Sargent",
"Powers"
],
[
"Campos",
"Olsen"
],
[
"Savannah",
"Kirby"
]
],
"size": 5,
"status": 200
}
이후 페이지를 가져오려면 이전 응답의 cursor를 사용하세요.
POST /_plugins/_sql
{
"cursor": "d:eyJhIj...NTF9"
}
다음 응답에는 결과의 datarows와 새 cursor만 포함돼요.
{
"cursor": "d:eyJhIj...2345",
"datarows": [
[
"Abbey",
"Karen"
],
[
"Chen",
"Ken"
],
[
"Ani",
"Jade"
],
[
"Peng",
"Hu"
],
[
"John",
"Doe"
]
]
}
중첩 필드가 평탄화되는 경우 datarows에 fetch_size보다 많은 레코드가 있을 수 있어요.
마지막 결과 페이지에는 datarows만 있고 cursor가 없어요. cursor 컨텍스트는 마지막 페이지에서 자동으로 정리돼요.
커서 컨텍스트를 명시적으로 지우려면 _plugins/_sql/close 엔드포인트 연산을 사용하세요.
POST /_plugins/_sql/close
{
"cursor": "d:eyJhIj...NTF9"
}
응답은 OpenSearch의 확인(acknowledgment)이에요.
{"succeeded":true}
결과 필터링 (Filtering results)
filter 파라미터를 사용해 OpenSearch DSL에 조건을 직접 추가할 수 있어요.
다음 SQL 질의는 모든 고객의 이름과 계좌 잔액을 반환해요. 이후 결과가 잔액이 $10,000 미만인 고객만 포함하도록 필터링돼요.
POST /_plugins/_sql/
{
"query" : "SELECT firstname, lastname, balance FROM accounts",
"filter" : {
"range" : {
"balance" : {
"lt" : 10000
}
}
}
}
응답에는 일치하는 결과가 포함돼요.
{
"schema": [
{
"name": "firstname",
"type": "text"
},
{
"name": "lastname",
"type": "text"
},
{
"name": "balance",
"type": "long"
}
],
"total": 2,
"datarows": [
[
"Hattie",
"Bond",
5686
],
[
"Dale",
"Adams",
4180
]
],
"size": 2,
"status": 200
}
Explain API를 사용해 이 질의가 OpenSearch에 대해 어떻게 실행되는지 확인할 수 있어요.
POST /_plugins/_sql/_explain
{
"query" : "SELECT firstname, lastname, balance FROM accounts",
"filter" : {
"range" : {
"balance" : {
"lt" : 10000
}
}
}
}
응답에는 앞의 질의에 해당하는 OpenSearch DSL의 Boolean 질의가 포함돼요.
{
"from": 0,
"size": 200,
"query": {
"bool": {
"filter": [{
"bool": {
"filter": [{
"range": {
"balance": {
"from": null,
"to": 10000,
"include_lower": true,
"include_upper": false,
"boost": 1.0
}
}
}],
"adjust_pure_negative": true,
"boost": 1.0
}
}],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"_source": {
"includes": [
"firstname",
"lastname",
"balance"
],
"excludes": []
}
}
파라미터 사용하기 (Using parameters)
parameters 필드를 사용해 준비된(prepared) SQL 질의에 파라미터 값을 전달할 수 있어요.
다음 explain 연산은 age 파라미터가 있는 SQL 질의를 사용해요.
POST /_plugins/_sql/_explain
{
"query": "SELECT * FROM accounts WHERE age = ?",
"parameters": [{
"type": "integer",
"value": 30
}]
}
응답에는 앞의 SQL 질의에 해당하는 OpenSearch DSL의 Boolean 질의가 포함돼요.
{
"from": 0,
"size": 200,
"query": {
"bool": {
"filter": [{
"bool": {
"must": [{
"term": {
"age": {
"value": 30,
"boost": 1.0
}
}
}],
"adjust_pure_negative": true,
"boost": 1.0
}
}],
"adjust_pure_negative": true,
"boost": 1.0
}
}
}
관련 문서 (Related documentation)
- Data source APIs