All Products
Search
Document Center

Elasticsearch:Query syntax

Last Updated:Mar 25, 2026

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:

SQLElasticsearch
TableIndex
RowDocument
ColumnField

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

ParameterTypeRequiredDescription
prettyURL parameterNoFormats the response for readability.
queryStringYesThe SQL statement to execute. Example: select * from monitor where host='100.80.xx.xx' limit 5
fetch_sizeIntegerNoThe number of results to return per response. Default: 1000. Maximum: 10000. If the value exceeds 10000, the system uses 10000.
paramsArrayNoTyped 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****"
}
FieldData typeDescription
columnsArrayThe names and data types of the queried fields.
rows2D arrayThe query results. Each inner array is one matching document.
cursorStringA 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

ParameterTypeRequiredDescription
prettyURL parameterNoFormats the response for readability.
cursorStringYesThe 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

FunctionSignatureExampleDescription
ABSABS(number) -> numberSELECT ABS(num_field) FROM tableReturns the absolute value.
ACOSACOS(number) -> doubleSELECT ACOS(num_field) FROM tableReturns the arccosine.
ASINASIN(number) -> doubleSELECT ASIN(num_field) FROM tableReturns the arcsine.
ATANATAN(number) -> doubleSELECT ATAN(num_field) FROM tableReturns the arctangent.
ATAN2ATAN2(number, number) -> doubleSELECT ATAN2(num_field1,num_field2) FROM tableReturns the arctangent of two numbers.
CBRTCBRT(number) -> doubleSELECT CBRT(num_field) FROM tableReturns the double-precision cube root.
CEILCEIL(number) -> integerSELECT CEIL(num_field) FROM tableReturns the smallest integer greater than or equal to the input.
COSCOS(number) -> doubleSELECT COS(num_field) FROM tableReturns the cosine.
COTCOT(number) -> doubleSELECT COT(num_field) FROM tableReturns the cotangent.
DEGREESDEGREES(number) -> doubleSELECT DEGREES(num_field) FROM tableConverts radians to degrees.
EXP or EXPM1EXP(number) -> doubleSELECT EXP(num_field) FROM tableReturns e raised to the power of the input.
FLOORFLOOR(number) -> integerSELECT FLOOR(num_field) FROM tableReturns the largest integer less than or equal to the input.
LNLN(number) -> doubleSELECT LN(num_field) FROM tableReturns the natural logarithm.
LOG10LOG10(number) -> doubleSELECT LOG10(num_field) FROM tableReturns the base-10 logarithm.
PIPI() -> doubleSELECT PI() FROM tableReturns the value of pi.
POWERPOWER(number, number) -> doubleSELECT POWER(num_field,2) FROM tableReturns the result of raising a number to a power.
RADIANSRADIANS(number) -> doubleSELECT RADIANS(num_field) FROM tableConverts degrees to radians.
RANDRAND() -> doubleSELECT RAND() FROM tableReturns a random double in the range [0.0, 1.0).
ROUNDROUND(number, integer) -> numberSELECT ROUND(num_field,2) FROM tableRounds to the specified number of decimal places.
SINSIN(number) -> doubleSELECT SIN(num_field) FROM tableReturns the sine.
SINHSINH(number) -> doubleSELECT SINH(num_field) FROM tableReturns the hyperbolic sine.
SQRTSQRT(number) -> doubleSELECT SQRT(num_field) FROM tableReturns the positive square root.
TANTAN(number) -> doubleSELECT TAN(num_field) FROM tableReturns the tangent.
TRUNCATETRUNCATE(number, integer) -> numberSELECT TRUNCATE(num_field,2) FROM tableTruncates to the specified number of decimal places.

String functions

FunctionSignatureExampleDescription
ASCIIASCII(string) -> integerSELECT ASCII(str_field) FROM tableReturns the ASCII value of the first character.
CHAR_LENGTH or CHARACTER_LENGTHCHAR_LENGTH(string) -> integerSELECT CHAR_LENGTH(str_field) FROM tableReturns the length of the string in bytes.
CONCATCONCAT(string, ...) -> stringSELECT CONCAT(str_field,'test') FROM tableConcatenates two or more strings.
LCASE or LOWERLCASE(string) -> stringSELECT LCASE(str_field) FROM tableConverts the string to lowercase.
LEFTLEFT(string, integer) -> stringSELECT LEFT(str_field, 3) FROM tableReturns the specified number of leftmost characters.
LPADLPAD(string, integer, string) -> stringSELECT LPAD(str_field, 20, 'ABC') FROM tableLeft-pads the string to the specified length with the pad string.
POSITIONPOSITION(string IN string) -> integerSELECT POSITION('test' IN str_field) FROM tableReturns the position of the first occurrence of a substring.
REPEATREPEAT(string, integer) -> stringSELECT REPEAT(str_field, 3) FROM tableRepeats the string the specified number of times.
REPLACEREPLACE(string, string, string) -> stringSELECT REPLACE(str_field, 'SQL', 'HTML') FROM tableReplaces all occurrences of a substring with a new substring.
REVERSEREVERSE(string) -> stringSELECT REVERSE(str_test) FROM tableReverses the string.
RIGHTRIGHT(string, integer) -> stringSELECT RIGHT(str_field, 3) FROM tableReturns the specified number of rightmost characters.
SPACESPACE(integer) -> stringSELECT SPACE(num_field) FROM tableReturns a string of the specified number of spaces.
SUBSTRINGSUBSTRING(string, integer, integer) -> stringSELECT SUBSTRING(str_field, 5, 3) FROM tableExtracts a substring starting at the specified position.
TRIMTRIM(string) -> stringSELECT TRIM(str_field) FROM tableRemoves leading and trailing spaces.
UCASE or UPPERUCASE(string) -> stringSELECT UCASE(str_field) FROM tableConverts the string to uppercase.

Date functions

FunctionSignatureExampleDescription
CURRENT_DATECURRENT_DATE() -> dateSELECT CURRENT_DATE() FROM tableReturns the current date.
CURRENT_TIMECURRENT_TIME() -> timeSELECT CURRENT_TIME() FROM tableReturns the current time.
CURRENT_TIMESTAMPCURRENT_TIMESTAMP() -> timestampSELECT CURRENT_TIMESTAMP() FROM tableReturns the current date and time.
DATE_FORMATDATE_FORMAT(date, string) -> stringSELECT DATE_FORMAT(date_field,'yyyy') FROM date_testFormats a date or time using the specified pattern.
DAYNAMEDAYNAME(date) -> stringSELECT DAYNAME(date_field) FROM tableReturns the name of the day of the week.
DAYOFMONTHDAYOFMONTH(date) -> integerSELECT DAYOFMONTH(date_field) FROM tableReturns the day of the month (1–31).
DAYOFWEEKDAYOFWEEK(date) -> integerSELECT DAYOFWEEK(date_field) FROM tableReturns the index of the day of the week.
DAYOFYEARDAYOFYEAR(date) -> integerSELECT DAYOFYEAR(date_field) FROM tableReturns the day of the year (1–366).
EXTRACTEXTRACT(part FROM date) -> integerSELECT EXTRACT(MONTH FROM date_field) FROM tableExtracts the specified part (year, month, day, hour, or minute) from a date or time.
HOURHOUR(date) -> integerSELECT HOUR(date_field) FROM tableReturns the hour part.
LAST_DAYLAST_DAY(date) -> dateSELECT LAST_DAY(date_field) FROM tableReturns the last day of the month.
MINUTEMINUTE(time) -> integerSELECT MINUTE(date_field) FROM tableReturns the minute part.
MONTHMONTH(date) -> integerSELECT MONTH(date_field) FROM tableReturns the month (1–12).
MONTHNAMEMONTHNAME(date) -> stringSELECT MONTHNAME(date_field) FROM tableReturns the name of the month.
QUARTERQUARTER(date) -> integerSELECT QUARTER(date_field) FROM tableReturns the quarter of the year (1–4).
SECONDSECOND(time) -> integerSELECT SECOND(date_field) FROM tableReturns the second part.
WEEKWEEK(date) -> integerSELECT WEEK(date_field) FROM tableReturns the week index. Valid values: 1–54 (differs from MySQL's 0–53).
YEARYEAR(date) -> integerSELECT YEAR(date_field) FROM tableReturns the year part.

Aggregation functions

FunctionSignatureExampleDescription
AVGAVG(number) -> doubleSELECT AVG(num_field) FROM tableReturns the average of the values.
COUNTCOUNT(field) -> integerSELECT COUNT(num_field) FROM tableReturns the number of matching records.
MAXMAX(T) -> TSELECT MAX(num_field) FROM tableReturns the maximum value.
MINMIN(T) -> TSELECT MIN(num_field) FROM tableReturns the minimum value.
SUMSUM(number) -> numberSELECT SUM(num_field) FROM tableReturns the sum of the values.

Arithmetic operations

OperatorExampleDescription
+SELECT (v1 + v2) as v FROM tableAddition.
-SELECT (v1 - v2) as v FROM tableSubtraction.
*SELECT (v1 * v2) as v FROM tableMultiplication.
/SELECT (v1 / v2) as v FROM tableDivision.
%SELECT (v1 % v2) as v FROM tableModulo (remainder).

Logical operations

OperatorExampleDescription
ANDSELECT * FROM table WHERE condition AND conditionBoth conditions must be true.
ORSELECT * FROM table WHERE condition OR conditionAt least one condition must be true.
NOTSELECT * FROM table WHERE NOT conditionNegates the condition.
IS NULLSELECT * FROM table WHERE field IS NULLMatches documents where the field is null.
IS NOT NULLSELECT * FROM table WHERE field IS NOT NULLMatches documents where the field is not null.

Advanced functions

FunctionSyntaxExampleDescription
CASECASE WHEN condition THEN value ELSE value ENDSELECT * 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.