SQL 和 PPL API

使用 SQL 和 PPL API 向 SQL 插件发送查询。使用 _sql 端点发送 SQL 查询,使用 _ppl 端点发送 PPL 查询。对于这两种查询,您还可以使用 _explain 端点将查询翻译成UDB-SX 领域特定语言 (DSL) 或用于排查错误。

查询 API

向 SQL 插件发送 SQL/PPL 查询。您可以通过查询参数指定响应格式。

查询参数

参数 数据类型 描述
format 字符串 响应格式。_sql 端点支持 jdbccsvrawjson 格式。_ppl 端点支持 jdbccsvraw 格式。默认为 jdbc
sanitize 布尔值 指定是否对结果中的特殊字符进行转义。更多信息请参阅 响应格式。默认为 true

请求体字段

字段 数据类型 描述
query 字符串 要执行的查询。必需。
filter JSON 对象 结果过滤器。可选。
fetch_size 整数 单次响应返回的结果数量。用于结果分页。默认为 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,
      "amberduke@pyrami.com",
      "Duke"
    ],
    [
      6,
      "Hattie",
      "671 Bristol Street",
      5686,
      "M",
      "Dante",
      "Netagy",
      "TN",
      36,
      "hattiebond@netagy.com",
      "Bond"
    ],
    [
      13,
      "Nanette",
      "789 Madison Street",
      32838,
      "F",
      "Nogal",
      "Quility",
      "VA",
      28,
      "nanettebates@quility.com",
      "Bates"
    ],
    [
      18,
      "Dale",
      "467 Hutchinson Court",
      4180,
      "M",
      "Orick",
      null,
      "MD",
      33,
      "daleadams@boink.com",
      "Adams"
    ]
  ],
  "total": 4,
  "size": 4,
  "status": 200
}

响应体字段

字段 数据类型 描述
schema 数组 指定所有字段的字段名和类型。
data_rows 二维数组 结果数组。每个结果代表一个匹配行(文档)。
total 整数 索引中的总行数(文档数)。
size 整数 单次响应返回的结果数量。
status 字符串 UDB-SX 执行查询后返回的 HTTP 响应状态。

Explain API

SQL 插件提供 explain 功能,用于展示查询是如何在 UDB-SX 上执行的,这对调试和开发很有帮助。向 _plugins/_sql/_explain_plugins/_ppl/_explain 端点发送 POST 请求,会返回UDB-SX 领域特定语言 (DSL) 的 JSON 格式说明,解释该查询。 您可以使用 curl 在命令行或 Dashboards 控制台中执行 explain API 操作,如下例所示。

SQL 查询的 explain 请求示例

POST _plugins/_sql/_explain
{
  "query": "SELECT firstname, lastname FROM accounts WHERE age > 20"
}

SQL 查询的 explain 响应示例

{
  "root": {
    "name": "ProjectOperator",
    "description": {
      "fields": "[firstname, lastname]"
    },
    "children": [
      {
        "name": "UDB-SXIndexScan",
        "description": {
          "request": """UDB-SXQueryRequest(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": []
      }
    ]
  }
}

PPL 查询的 explain 请求示例

POST _plugins/_ppl/_explain
{
  "query" : "source=accounts | fields firstname, lastname"
}

PPL 查询的 explain 响应示例

{
  "root": {
    "name": "ProjectOperator",
    "description": {
      "fields": "[firstname, lastname]"
    },
    "children": [
      {
        "name": "UDB-SXIndexScan",
        "description": {
          "request": """UDB-SXQueryRequest(indexName=accounts, sourceBuilder={"from":0,"size":200,"timeout":"1m","_source":{"includes":["firstname","lastname"],"excludes":[]}}, searchDone=false)"""
        },
        "children": []
      }
    ]
  }
}

对于需要后处理的查询,explain 响应除了 UDB-SX DSL 外,还会包含查询计划。对于不需要后处理的查询,您可以看到完整的 DSL。

分页结果

要获取分页响应,请使用 fetch_size 参数。fetch_size 的值应大于 0。默认值为 1,000。值为 0 将退回到非分页响应。

fetch_size 参数仅支持 jdbc 响应格式。

示例

以下请求包含一个 SQL 查询,并指定每次返回五个结果:

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:eyJhIjp7fSwicyI6IkRYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQU1XZWpkdFRFRkZUMlpTZEZkeFdsWnJkRlZoYnpaeVVRPT0iLCJjIjpbeyJuYW1lIjoiZmlyc3RuYW1lIiwidHlwZSI6InRleHQifSx7Im5hbWUiOiJsYXN0bmFtZSIsInR5cGUiOiJ0ZXh0In1dLCJmIjo1LCJpIjoiYWNjb3VudHMiLCJsIjo5NTF9",
  "total": 956,
  "datarows": [
    [
      "Cherry",
      "Carey"
    ],
    [
      "Lindsey",
      "Hawkins"
    ],
    [
      "Sargent",
      "Powers"
    ],
    [
      "Campos",
      "Olsen"
    ],
    [
      "Savannah",
      "Kirby"
    ]
  ],
  "size": 5,
  "status": 200
}

要获取后续页面,请使用先前响应中的 cursor

POST /_plugins/_sql 
{
   "cursor": "d:eyJhIjp7fSwicyI6IkRYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQU1XZWpkdFRFRkZUMlpTZEZkeFdsWnJkRlZoYnpaeVVRPT0iLCJjIjpbeyJuYW1lIjoiZmlyc3RuYW1lIiwidHlwZSI6InRleHQifSx7Im5hbWUiOiJsYXN0bmFtZSIsInR5cGUiOiJ0ZXh0In1dLCJmIjo1LCJpIjoiYWNjb3VudHMiLCJsIjo5NTF9"
}

下一个响应仅包含结果的 datarows 和一个新的 cursor

{
  "cursor": "d:eyJhIjp7fSwicyI6IkRYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQU1XZWpkdFRFRkZUMlpTZEZkeFdsWnJkRlZoYnpaeVVRPT0iLCJjIjpbeyJuYW1lIjoiZmlyc3RuYW1lIiwidHlwZSI6InRleHQifSx7Im5hbWUiOiJsYXN0bmFtZSIsInR5cGUiOiJ0ZXh0In1dLCJmIjo1LCJpIjoiYWNjb3VudHMabcde12345",
  "datarows": [
    [
      "Abbey",
      "Karen"
    ],
    [
      "Chen",
      "Ken"
    ],
    [
      "Ani",
      "Jade"
    ],
    [
      "Peng",
      "Hu"
    ],
    [
      "John",
      "Doe"
    ]
  ]
}

当嵌套字段被扁平化时,datarows 可能包含超过 fetch_size 指定数量的记录。

最后一页结果只有 datarows,没有 cursorcursor 上下文在最后一页会自动清除。

要显式清除游标上下文,请使用 _plugins/_sql/close 端点操作:

POST /_plugins/_sql/close 
{
   "cursor": "d:eyJhIjp7fSwicyI6IkRYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQU1XZWpkdFRFRkZUMlpTZEZkeFdsWnJkRlZoYnpaeVVRPT0iLCJjIjpbeyJuYW1lIjoiZmlyc3RuYW1lIiwidHlwZSI6InRleHQifSx7Im5hbWUiOiJsYXN0bmFtZSIsInR5cGUiOiJ0ZXh0In1dLCJmIjo1LCJpIjoiYWNjb3VudHMiLCJsIjo5NTF9"
}'

响应是 UDB-SX 的确认信息:

{"succeeded":true}

结果过滤

您可以使用 filter 参数直接向 UDB-SX 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 查看此查询是如何在 UDB-SX 上执行的:

POST /_plugins/_sql/_explain 
{
  "query" : "SELECT firstname, lastname, balance FROM accounts",
  "filter" : {
    "range" : {
      "balance" : {
        "lt" : 10000
      }
    }
  }
}'

响应包含与上述查询相对应的 UDB-SX DSL 布尔查询:

{
  "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": []
  }
}

使用参数

您可以使用 parameters 字段向预编译的 SQL 查询传递参数值。

以下 explain 操作使用了一个带有 age 参数的 SQL 查询:

POST /_plugins/_sql/_explain 
{
  "query": "SELECT * FROM accounts WHERE age = ?",
  "parameters": [{
    "type": "integer",
    "value": 30
  }]
}

响应包含与上述 SQL 查询相对应的 UDB-SX DSL 布尔查询:

{
  "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
    }
  }
}