The aliyun-sql plug-in supports the following query types: basic queries, paginated queries with cursors, JSON-formatted queries, translate queries, special queries (nested and text data types), user-defined functions (UDFs), and a set of built-in functions and expressions.
To test queries interactively, use the Kibana console. For setup instructions, see Use method.
Key concepts
Map your SQL knowledge to Elasticsearch terminology before writing queries:
| SQL | Elasticsearch |
|---|---|
| Table | Index |
| Row | Document |
| Column | Field |
The plug-in is built on Apache Calcite and translates SQL statements to Elasticsearch domain-specific language (DSL) queries at runtime.
Basic queries
All basic queries use the POST /_alisql endpoint.
Common query
POST /_alisql?pretty
{
"query": "select * from monitor where host='100.80.xx.xx' limit 5"
}Query with a fetch size
POST /_alisql?pretty
{
"query": "select * from monitor",
"fetch_size": 3
}Parameterized query
Use params to pass typed values into a query, similar to the PreparedStatement interface in JDBC:
POST /_alisql?pretty
{
"query": "select * from monitor where host= ? ",
"params": [{"type":"STRING","value":"100.80.xx.xx"}],
"fetch_size": 1
}Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
pretty | URL parameter | No | Formats the response for readability. |
query | String | Yes | The SQL statement to execute. Example: select * from monitor where host='100.80.xx.xx' limit 5 |
fetch_size | Integer | No | The number of results to return per response. Default: 1000. Maximum: 10000. If the value exceeds 10000, the system uses 10000. |
params | Array | No | Typed parameter values for parameterized queries. Example: [{"type":"STRING","value":"100.80.xx.xx"}] |
`limit` vs `fetch_size`: Both constrain results, but they work differently:
limit: restricts total results, supports full or range queries.fetch_size: controls page size for cursor-based pagination, similar to the Scroll API.
Response fields
A typical response:
{
"columns": [
{"name": "times", "type": "integer"},
{"name": "value2", "type": "float"},
{"name": "host", "type": "keyword"},
{"name": "region", "type": "keyword"},
{"name": "measurement", "type": "keyword"},
{"name": "timestamp", "type": "date"}
],
"rows": [
[572575, 4649800.0, "100.80.xx.xx", "china-dd", "cpu", "2018-08-09T08:18:42.000Z"]
],
"cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****"
}| Field | Data type | Description |
|---|---|---|
columns | Array | The names and data types of the queried fields. |
rows | 2D array | The query results. Each inner array is one matching document. |
cursor | String | A cursor token for retrieving the next page of results. Present only when more results are available. |
By default, up to 1,000 results are returned. For larger result sets, use cursor-based pagination to retrieve all data.
Paginated queries
For large result sets, use cursor-based pagination.
Step 1 — Initial request with `fetch_size`:
POST /_alisql?pretty
{
"query": "select * from monitor",
"fetch_size": 3
}The response includes a cursor token when more data is available.
Step 2 — Continue with the cursor:
Pass the cursor value from the previous response to retrieve the next page:
POST /_alisql?pretty
{
"cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****"
}Cursor query responses omit the columns field to reduce network latency. All other fields follow the same structure as the initial response.
Step 3 — End condition:
Keep sending cursor requests until the response contains no cursor field or no rows. At that point, all data has been retrieved.
Cursor request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
pretty | URL parameter | No | Formats the response for readability. |
cursor | String | Yes | The cursor token from the previous response. |
JSON-formatted queries
Add format=org to return results in the same JSON format as native Elasticsearch DSL queries. JOIN statements are not supported.
POST /_alisql?format=org
{
"query": "select * from monitor where host= ? ",
"params": [{"type":"STRING","value":"100.80.xx.xx"}],
"fetch_size": 1
}The response uses the standard Elasticsearch hits structure:
{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAsWYXNEdlVJZzJTSXFfOGluOVB4Q3Z****",
"took": 18,
"timed_out": false,
"_shards": {"total": 1, "successful": 1, "skipped": 0, "failed": 0},
"hits": {
"total": 2,
"max_score": 1.0,
"hits": [
{
"_index": "monitor",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"times": 572575,
"value2": 4649800,
"host": "100.80.xx.xx",
"region": "china-dd",
"measurement": "cpu",
"timestamp": "2018-08-09T16:18:42+0800"
}
}
]
}
}Use the _scroll_id field for paged queries when working with this format. All other request parameters are the same as in basic queries.
Translate queries
The translate API converts a SQL statement to the equivalent Elasticsearch DSL query. Use it to debug queries or understand how the plug-in maps SQL conditions to DSL filters. JOIN statements are not supported.
POST _alisql/translate
{
"query": "select * from monitor where host= '100.80.xx.xx' "
}The response is the DSL equivalent of the SQL query:
{
"size": 1000,
"query": {
"constant_score": {
"filter": {
"term": {
"host": {
"value": "100.80.xx.xx",
"boost": 1.0
}
}
},
"boost": 1.0
}
},
"_source": {
"includes": ["times", "value2", "host", "region", "measurement", "timestamp"],
"excludes": []
}
}Special queries
The aliyun-sql plug-in supports querying fields of the nested and text data types, which are not directly queryable in standard SQL databases.
Step 1 — Create an index with nested and text fields:
PUT user_info/
{
"mappings": {
"_doc": {
"properties": {
"addr": {"type": "text"},
"age": {"type": "integer"},
"id": {"type": "integer"},
"name": {
"type": "nested",
"properties": {
"first_name": {"type": "keyword"},
"second_name": {"type": "keyword"}
}
}
}
}
}
}Step 2 — Insert documents in bulk:
PUT user_info/_doc/_bulk?refresh
{"index":{"_id":"1"}}
{"addr":"467 Hutchinson Court","age":80,"id":"1","name":[{"first_name":"lesi","second_name":"Adams"},{"first_name":"chaochaosi","second_name":"Aams"}]}
{"index":{"_id":"2"}}
{"addr":"671 Bristol Street","age":21,"id":"2","name":{"first_name":"Hattie","second_name":"Bond"}}
{"index":{"_id":"3"}}
{"addr":"554 Bristol Street","age":23,"id":"3","name":{"first_name":"Hattie","second_name":"Bond"}}Step 3 — Query a nested field:
Use dot notation to reference nested fields:
POST _alisql
{
"query": "select * from user_info where name.second_name='Adams'"
}Response:
{
"columns": [
{"name": "id", "type": "integer"},
{"name": "addr", "type": "text"},
{"name": "name.first_name", "type": "keyword"},
{"name": "age", "type": "integer"},
{"name": "name.second_name", "type": "keyword"}
],
"rows": [
[1, "467 Hutchinson Court", "lesi", 80, "Adams"]
]
}Step 4 — Query a text field:
Filter on a text type field using a keyword match:
POST _alisql
{
"query": "select * from user_info where addr='Bristol'"
}Response:
{
"columns": [
{"name": "id", "type": "integer"},
{"name": "addr", "type": "text"},
{"name": "name.first_name", "type": "keyword"},
{"name": "age", "type": "integer"},
{"name": "name.second_name", "type": "keyword"}
],
"rows": [
[2, "671 Bristol Street", "Hattie", 21, "Bond"],
[3, "554 Bristol Street", "Hattie", 23, "Bond"]
]
}Built-in functions and expressions
Numeric functions
| Function | Signature | Example | Description |
|---|---|---|---|
| ABS | ABS(number) -> number | SELECT ABS(num_field) FROM table | Returns the absolute value. |
| ACOS | ACOS(number) -> double | SELECT ACOS(num_field) FROM table | Returns the arccosine. |
| ASIN | ASIN(number) -> double | SELECT ASIN(num_field) FROM table | Returns the arcsine. |
| ATAN | ATAN(number) -> double | SELECT ATAN(num_field) FROM table | Returns the arctangent. |
| ATAN2 | ATAN2(number, number) -> double | SELECT ATAN2(num_field1,num_field2) FROM table | Returns the arctangent of two numbers. |
| CBRT | CBRT(number) -> double | SELECT CBRT(num_field) FROM table | Returns the double-precision cube root. |
| CEIL | CEIL(number) -> integer | SELECT CEIL(num_field) FROM table | Returns the smallest integer greater than or equal to the input. |
| COS | COS(number) -> double | SELECT COS(num_field) FROM table | Returns the cosine. |
| COT | COT(number) -> double | SELECT COT(num_field) FROM table | Returns the cotangent. |
| DEGREES | DEGREES(number) -> double | SELECT DEGREES(num_field) FROM table | Converts radians to degrees. |
| EXP or EXPM1 | EXP(number) -> double | SELECT EXP(num_field) FROM table | Returns e raised to the power of the input. |
| FLOOR | FLOOR(number) -> integer | SELECT FLOOR(num_field) FROM table | Returns the largest integer less than or equal to the input. |
| LN | LN(number) -> double | SELECT LN(num_field) FROM table | Returns the natural logarithm. |
| LOG10 | LOG10(number) -> double | SELECT LOG10(num_field) FROM table | Returns the base-10 logarithm. |
| PI | PI() -> double | SELECT PI() FROM table | Returns the value of pi. |
| POWER | POWER(number, number) -> double | SELECT POWER(num_field,2) FROM table | Returns the result of raising a number to a power. |
| RADIANS | RADIANS(number) -> double | SELECT RADIANS(num_field) FROM table | Converts degrees to radians. |
| RAND | RAND() -> double | SELECT RAND() FROM table | Returns a random double in the range [0.0, 1.0). |
| ROUND | ROUND(number, integer) -> number | SELECT ROUND(num_field,2) FROM table | Rounds to the specified number of decimal places. |
| SIN | SIN(number) -> double | SELECT SIN(num_field) FROM table | Returns the sine. |
| SINH | SINH(number) -> double | SELECT SINH(num_field) FROM table | Returns the hyperbolic sine. |
| SQRT | SQRT(number) -> double | SELECT SQRT(num_field) FROM table | Returns the positive square root. |
| TAN | TAN(number) -> double | SELECT TAN(num_field) FROM table | Returns the tangent. |
| TRUNCATE | TRUNCATE(number, integer) -> number | SELECT TRUNCATE(num_field,2) FROM table | Truncates to the specified number of decimal places. |
String functions
| Function | Signature | Example | Description |
|---|---|---|---|
| ASCII | ASCII(string) -> integer | SELECT ASCII(str_field) FROM table | Returns the ASCII value of the first character. |
| CHAR_LENGTH or CHARACTER_LENGTH | CHAR_LENGTH(string) -> integer | SELECT CHAR_LENGTH(str_field) FROM table | Returns the length of the string in bytes. |
| CONCAT | CONCAT(string, ...) -> string | SELECT CONCAT(str_field,'test') FROM table | Concatenates two or more strings. |
| LCASE or LOWER | LCASE(string) -> string | SELECT LCASE(str_field) FROM table | Converts the string to lowercase. |
| LEFT | LEFT(string, integer) -> string | SELECT LEFT(str_field, 3) FROM table | Returns the specified number of leftmost characters. |
| LPAD | LPAD(string, integer, string) -> string | SELECT LPAD(str_field, 20, 'ABC') FROM table | Left-pads the string to the specified length with the pad string. |
| POSITION | POSITION(string IN string) -> integer | SELECT POSITION('test' IN str_field) FROM table | Returns the position of the first occurrence of a substring. |
| REPEAT | REPEAT(string, integer) -> string | SELECT REPEAT(str_field, 3) FROM table | Repeats the string the specified number of times. |
| REPLACE | REPLACE(string, string, string) -> string | SELECT REPLACE(str_field, 'SQL', 'HTML') FROM table | Replaces all occurrences of a substring with a new substring. |
| REVERSE | REVERSE(string) -> string | SELECT REVERSE(str_test) FROM table | Reverses the string. |
| RIGHT | RIGHT(string, integer) -> string | SELECT RIGHT(str_field, 3) FROM table | Returns the specified number of rightmost characters. |
| SPACE | SPACE(integer) -> string | SELECT SPACE(num_field) FROM table | Returns a string of the specified number of spaces. |
| SUBSTRING | SUBSTRING(string, integer, integer) -> string | SELECT SUBSTRING(str_field, 5, 3) FROM table | Extracts a substring starting at the specified position. |
| TRIM | TRIM(string) -> string | SELECT TRIM(str_field) FROM table | Removes leading and trailing spaces. |
| UCASE or UPPER | UCASE(string) -> string | SELECT UCASE(str_field) FROM table | Converts the string to uppercase. |
Date functions
| Function | Signature | Example | Description |
|---|---|---|---|
| CURRENT_DATE | CURRENT_DATE() -> date | SELECT CURRENT_DATE() FROM table | Returns the current date. |
| CURRENT_TIME | CURRENT_TIME() -> time | SELECT CURRENT_TIME() FROM table | Returns the current time. |
| CURRENT_TIMESTAMP | CURRENT_TIMESTAMP() -> timestamp | SELECT CURRENT_TIMESTAMP() FROM table | Returns the current date and time. |
| DATE_FORMAT | DATE_FORMAT(date, string) -> string | SELECT DATE_FORMAT(date_field,'yyyy') FROM date_test | Formats a date or time using the specified pattern. |
| DAYNAME | DAYNAME(date) -> string | SELECT DAYNAME(date_field) FROM table | Returns the name of the day of the week. |
| DAYOFMONTH | DAYOFMONTH(date) -> integer | SELECT DAYOFMONTH(date_field) FROM table | Returns the day of the month (1–31). |
| DAYOFWEEK | DAYOFWEEK(date) -> integer | SELECT DAYOFWEEK(date_field) FROM table | Returns the index of the day of the week. |
| DAYOFYEAR | DAYOFYEAR(date) -> integer | SELECT DAYOFYEAR(date_field) FROM table | Returns the day of the year (1–366). |
| EXTRACT | EXTRACT(part FROM date) -> integer | SELECT EXTRACT(MONTH FROM date_field) FROM table | Extracts the specified part (year, month, day, hour, or minute) from a date or time. |
| HOUR | HOUR(date) -> integer | SELECT HOUR(date_field) FROM table | Returns the hour part. |
| LAST_DAY | LAST_DAY(date) -> date | SELECT LAST_DAY(date_field) FROM table | Returns the last day of the month. |
| MINUTE | MINUTE(time) -> integer | SELECT MINUTE(date_field) FROM table | Returns the minute part. |
| MONTH | MONTH(date) -> integer | SELECT MONTH(date_field) FROM table | Returns the month (1–12). |
| MONTHNAME | MONTHNAME(date) -> string | SELECT MONTHNAME(date_field) FROM table | Returns the name of the month. |
| QUARTER | QUARTER(date) -> integer | SELECT QUARTER(date_field) FROM table | Returns the quarter of the year (1–4). |
| SECOND | SECOND(time) -> integer | SELECT SECOND(date_field) FROM table | Returns the second part. |
| WEEK | WEEK(date) -> integer | SELECT WEEK(date_field) FROM table | Returns the week index. Valid values: 1–54 (differs from MySQL's 0–53). |
| YEAR | YEAR(date) -> integer | SELECT YEAR(date_field) FROM table | Returns the year part. |
Aggregation functions
| Function | Signature | Example | Description |
|---|---|---|---|
| AVG | AVG(number) -> double | SELECT AVG(num_field) FROM table | Returns the average of the values. |
| COUNT | COUNT(field) -> integer | SELECT COUNT(num_field) FROM table | Returns the number of matching records. |
| MAX | MAX(T) -> T | SELECT MAX(num_field) FROM table | Returns the maximum value. |
| MIN | MIN(T) -> T | SELECT MIN(num_field) FROM table | Returns the minimum value. |
| SUM | SUM(number) -> number | SELECT SUM(num_field) FROM table | Returns the sum of the values. |
Arithmetic operations
| Operator | Example | Description |
|---|---|---|
+ | SELECT (v1 + v2) as v FROM table | Addition. |
- | SELECT (v1 - v2) as v FROM table | Subtraction. |
* | SELECT (v1 * v2) as v FROM table | Multiplication. |
/ | SELECT (v1 / v2) as v FROM table | Division. |
% | SELECT (v1 % v2) as v FROM table | Modulo (remainder). |
Logical operations
| Operator | Example | Description |
|---|---|---|
AND | SELECT * FROM table WHERE condition AND condition | Both conditions must be true. |
OR | SELECT * FROM table WHERE condition OR condition | At least one condition must be true. |
NOT | SELECT * FROM table WHERE NOT condition | Negates the condition. |
IS NULL | SELECT * FROM table WHERE field IS NULL | Matches documents where the field is null. |
IS NOT NULL | SELECT * FROM table WHERE field IS NOT NULL | Matches documents where the field is not null. |
Advanced functions
| Function | Syntax | Example | Description |
|---|---|---|---|
| CASE | CASE WHEN condition THEN value ELSE value END | SELECT * FROM table ORDER BY (CASE WHEN exp1 THEN exp2 ELSE exp3 END) | Returns exp2 if exp1 is true, otherwise returns exp3. Equivalent to an IF-THEN-ELSE statement. |