Before you begin
The aliyun-sql plug-in no longer accepts new customers. Only existing customers can continue to use it. We recommend that you use the official Elasticsearch x-pack-sql plug-in instead. For more information, see sql-search-api.
The aliyun-sql plug-in lets you query data in Alibaba Cloud Elasticsearch using SQL statements. It is compatible with MySQL 5 syntax. This plug-in is compatible only with Alibaba Cloud Elasticsearch versions 6.7.0 and later, but earlier than 7.10.0. Supported versions include 6.7.0, 6.8.x, 7.4.0, and 7.7.1. Versions 7.10.0 and later are not supported.
Enable and disable the plug-in
Before you use the aliyun-sql plug-in, you must enable it in the Dev Tools of the Kibana console. To log on to the Kibana console, see Connect to a cluster using Kibana.
Enable the plug-in
In Kibana's Dev Tools, run the following command:
PUT _cluster/settings { "transient": { "aliyun.sql.enabled": true } }Disable and uninstall the plug-in
You must disable the configuration of the aliyun-sql plug-in before you uninstall it. Otherwise, the cluster restart triggered by the uninstallation will hang.
Disable the plugin configuration.
PUT _cluster/settings { "persistent": { "aliyun.sql.enabled": null } }If you uninstall the plug-in before you disable its configuration and the restart hangs, run the following command to clear the archived configuration and resume the restart:
PUT _cluster/settings { "persistent": { "archived.aliyun.sql.enabled": null } }
Quick Start
The following example shows how to use the aliyun-sql plug-in to write test data and run a JOIN query.
The aliyun-sql plug-in supports only query requests, not write requests. You can use the bulk API to write data.
Log on to the Kibana console of your Alibaba Cloud Elasticsearch instance.
For more information about how to log on to the Kibana console, see Connect to a cluster using Kibana.
In Kibana, go to Dev Tools > Console, and enter the student information and ranking data.
Student information data:
PUT stuinfo/_doc/_bulk?refresh {"index":{"_id":"1"}} {"id":572553,"name":"xiaoming","age":"22","addr":"addr1"} {"index":{"_id":"2"}} {"id":572554,"name":"xiaowang","age":"23","addr":"addr2"} {"index":{"_id":"3"}} {"id":572555,"name":"xiaoliu","age":"21","addr":"addr3"}Student ranking data:
PUT sturank/_doc/_bulk?refresh {"index":{"_id":"1"}} {"id":572553,"score":"90","sorder":"5"} {"index":{"_id":"2"}} {"id":572554,"score":"92","sorder":"3"} {"index":{"_id":"3"}} {"id":572555,"score":"86","sorder":"10"}Use a JOIN query to retrieve the names and rankings of the students.
POST /_alisql { "query":"select stuinfo.name,sturank.sorder from stuinfo join sturank on stuinfo.id=sturank.id" }In the response, the columns field contains the column names and types, and the rows field contains the row data:
{ "columns" : [ { "name" : "name", "type" : "text" }, { "name" : "sorder", "type" : "text" } ], "rows" : [ [ "xiaoming", "5" ], [ "xiaowang", "3" ], [ "xiaoliu", "10" ] ] }
Basic queries
You can run all SQL queries using the POST /_alisql endpoint.
Simple query
POST /_alisql?pretty { "query": "select * from monitor where host='100.80.xx.xx' limit 5" }Set the number of results to return
POST /_alisql?pretty { "query": "select * from monitor", "fetch_size": 3 }Parameterized query
POST /_alisql?pretty { "query": "select * from monitor where host= ? ", "params": [{"type":"STRING","value":"100.80.xx.xx"}], "fetch_size": 1 }
Request parameters
Parameter type | Parameter name | Required | Example | Description |
URL parameter | pretty | No | None | Format the response for readability. |
Request body parameter | query | Yes |
| An SQL query statement. |
Request body parameter | fetch_size | No |
| The number of rows to return per query. Default: 1000. Maximum: 10000. If you set a value greater than 10000, the system uses 10000. The limit clause supports full or range queries. fetch_size works like a scroll query. |
Request body parameter | params | No |
| Supports parameterized queries similar to PreparedStatement. |
Response
For large queries, the first response returns a number of rows that is specified by the fetch_size parameter and includes a cursor.
{
"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****"
}Parameter | Description |
columns | Contains name and type. Shows the name and type of each field. |
rows | The query results. |
cursor | A cursor for pagination. |
By default, each response returns 1,000 rows. If the result set contains more than 1,000 rows, you can continue to use the cursor to fetch the remaining rows until the response no longer includes a cursor or returns no data.
Scroll queries
Use the cursor from the previous query to retrieve the next page of data.
Query request
POST /_alisql?pretty { "cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****" }Parameter type
Parameter
Is it required?
Description
URL parameter
pretty
No
Format the response for readability.
Request body parameter
cursor
Yes
The cursor value to fetch the corresponding data.
Response
{ "rows": [ [ 572547, 3.327459E7, "100.80.xx.xx", "china-dd", "cpu", "2018-08-09T08:19:12.000Z" ] ], "cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****" }The response is similar to that of a basic query, but the columns field is omitted to reduce network traffic.
JSON format queries
You can use the format=org parameter to return results in the raw Elasticsearch JSON format. This mode does not support JOIN queries.
Query request
POST /_alisql?format=org { "query": "select * from monitor where host= ? ", "params": [{"type":"STRING","value":"100.80.xx.xx"}], "fetch_size": 1 }The other query parameters are the same as those for basic queries.
Response
{ "_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" } } ] } }The response format matches that of the original DSL query. You can use the
_scroll_idparameter for pagination.
Translate queries
You can convert an SQL statement into an Elasticsearch Domain-Specific Language (DSL) statement. This feature does not support JOIN queries.
Query request
POST _alisql/translate { "query": "select * from monitor where host= '100.80.xx.xx' " }Response
{ "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": [ ] } }
JOIN queries
The aliyun-sql plug-in supports only inner joins, which are implemented using merge joins. Note the following limits:
The JOIN field must be strictly increasing or decreasing in relation to the Elasticsearch document ID.
The JOIN field must be numeric. String fields are not supported.
By default, the maximum number of rows that can be returned per table is 10,000.
Syntax:
SELECT
expression
FROM table_name
JOIN table_name
ON expression
[WHERE condition]You can change the maximum number of rows per table using the dynamic cluster parameter max.join.size. For example, to set the maximum number of rows to 20,000, run the following command:
PUT /_cluster/settings
{
"transient": {
"max.join.size": 20000
}
}Queries for nested and text fields
The aliyun-sql plug-in supports queries for nested and text fields.
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" } } } } } } }Perform a bulk insert.
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"}}Query the
second_namefield of the nested type.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" ] ] }Query the
addrfield of the text type.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" ] ] }
Custom UDF functions
You can register User-Defined Functions (UDFs) only during plug-in initialization. You cannot add UDFs dynamically. The following example shows how to extend the date_format method.
Define a
DateFormatclass that is based on the UDF./** * DateFormat. */ public class DateFormat extends UDF { public String eval(DateTime time, String toFormat) { if (time == null || toFormat == null) { return null; } Date date = time.toDate(); SimpleDateFormat format = new SimpleDateFormat(toFormat); return format.format(date); } }Add the
DateFormatclass to the plug-in initialization method.udfTable.add(KeplerSqlUserDefinedScalarFunction .create("date_format" , DateFormat.class , (JavaTypeFactoryImpl) typeFactory));Use the UDF in a query.
select date_format(date_f,'yyyy') from date_test
SQL syntax overview
Basic query syntax
SELECT [DISTINCT] (* | expression) [[AS] alias] [, ...]
FROM table_name
[WHERE condition]
[GROUP BY expression [, ...]
[HAVING condition]]
[ORDER BY expression [ ASC | DESC ] [, ...]]
[LIMIT [offset, ] size]JOIN query syntax
SELECT
expression
FROM table_name
JOIN table_name
ON expression
[WHERE condition]Functions and expressions
Type | Name | Example | Description |
Numeric function | ABS |
| Return the absolute value of a number. |
Numeric function | ACOS |
| Return the arccosine of a number. |
Numeric function | ASIN |
| Return the arcsine of a number. |
Numeric function | ATAN |
| Return the arctangent of a number. |
Numeric function | ATAN2 |
| Return the arctangent of two numbers. |
Numeric function | CEIL |
| Return the smallest integer greater than or equal to a number. |
Numeric function | CBRT |
| Return the double-precision cube root of a number. |
Numeric function | COS |
| Return the cosine of a number. |
Numeric function | COT |
| Return the cotangent of a number. |
Numeric function | DEGREES |
| Convert radians to degrees. |
Numeric function | EXP or EXPM1 |
| Return e raised to the power of a number. |
Numeric function | FLOOR |
| Return the largest integer less than or equal to a number. |
Numeric function | SIN |
| Return the sine of a number. |
Numeric function | SINH |
| Return the hyperbolic sine of a number. |
Numeric function | SQRT |
| Return the positive square root of a number. |
Numeric function | TAN |
| Return the tangent of a number. |
Numeric function | ROUND |
| Round a number to a specified number of decimal places. |
Numeric function | RADIANS |
| Convert degrees to radians. |
Numeric function | RAND |
| Return a positive double-precision value between 0.0 and 1.0. |
Numeric function | LN |
| Return the natural logarithm of a number. |
Numeric function | LOG10 |
| Return the base-10 logarithm of a number. |
Numeric function | PI |
| Return the value of π. |
Numeric function | POWER |
| Return a number raised to a specified power. |
Numeric function | TRUNCATE |
| Truncate a number to a specified number of decimal places. |
Arithmetic operator | + |
| Return the sum of two numbers. |
Arithmetic operator | - |
| Return the difference of two numbers. |
Arithmetic operator | * |
| Return the product of two numbers. |
Arithmetic operator | / |
| Return the quotient of two numbers. |
Arithmetic operator | % |
| Return the remainder after division. |
Logical operator | AND |
| Return data that meets both conditions. |
Logical operator | OR |
| Return data that meets either condition. |
Logical operator | NOT |
| Return data that does not meet the condition. |
Logical operator | IS NULL |
| Return data when the specified field is empty. |
Logical operator | IS NOT NULL |
| Return data when the specified field is not empty. |
String function | ASCII |
| Return the ASCII value of a character. |
String function | LCASE or LOWER |
| Convert a string to lowercase. |
String function | UCASE or UPPER |
| Convert a string to uppercase. |
String function | CHAR_LENGTH or CHARACTER_LENGTH |
| Return the length of a string in bytes. |
String function | TRIM |
| Remove leading and trailing spaces from a string. |
String function | SPACE |
| Return a string of a specified number of spaces. |
String function | LEFT |
| Extract characters from the left side of a string. |
String function | RIGHT |
| Extract characters from the right side of a string. |
String function | REPEAT |
| Repeat a string a specified number of times. |
String function | REPLACE |
| Replace all occurrences of a substring with another substring. |
String function | POSITION |
| Return the position of the first occurrence of a substring. |
String function | REVERSE |
| Returns the reversed string. |
String function | LPAD |
| Pad a string on the left with a specified character to a specified length. |
String function | CONCAT |
| You can combine two or more expressions. |
String function | SUBSTRING |
| Extract a substring starting at any position. |
Date function | CURRENT_DATE |
| Return the current date. |
Date function | CURRENT_TIME |
| Return the current time. |
Date function | CURRENT_TIMESTAMP |
| Return the current date and time. |
Date function | DAYNAME |
| Return the day-of-week name for a date. |
Date function | DAYOFMONTH |
| Returns the month of the specified date. |
Date function | DAYOFYEAR |
| Return the day of the year for a date. |
Date function | DAYOFWEEK |
| Return the day-of-week index for a date. |
Date function | HOUR |
| Return the hour part of a date. |
Date function | MINUTE |
| Return the minute part of a time or datetime. |
Date function | SECOND |
| Return the second part of a time or datetime. |
Date function | YEAR |
| Return the year part of a date. |
Date function | MONTH |
| Return the month part of a date. |
Date function | WEEK |
| Return the week number for a date (1–54). MySQL uses 0–53. |
Date function | MONTHNAME |
| Return the month name for a date. |
Date function | LAST_DAY |
| Return the last day of the month for a date. |
Date function | QUARTER |
| Return the quarter for a date. |
Date function | EXTRACT |
| Return a specific part of a date or time, such as year, month, day, hour, or minute. |
Date function | DATE_FORMAT |
| Format a date or time. |
Aggregation function | MIN |
| Return the minimum value in a set. |
Aggregation function | MAX |
| Return the maximum value in a set. |
Aggregation function | AVG |
| Return the average value in a set. |
Aggregation function | SUM |
| Return the sum of values in a set. |
Aggregation function | COUNT |
| Return the number of records that match a condition. |
Advanced function | CASE |
| Use CASE WHEN THEN ELSE END. Return the value in THEN when the condition in WHEN is met. Otherwise, return the value in ELSE. You can use this in SELECT, WHERE, and ORDER clauses. It works like IF THEN ELSE. |