通过aliyun-sql插件查询数据(已停止新客户服务)

更新时间:
复制为 MD 格式

使用前须知

aliyun-sql插件已停止对新客户提供服务,仅存量客户可继续使用。推荐使用Elastic官方的x-pack-sql插件替代,详情请参见sql-search-api

aliyun-sql插件支持使用SQL语句查询Elasticsearch中的数据,兼容MySQL 5语法。该插件仅适用于6.7.0及以上且低于7.10.0版本的阿里云Elasticsearch实例(即6.7.0、6.8.x、7.4.0、7.7.1等版本,不含7.10.0及以上版本)。

开启和关闭插件

使用aliyun-sql插件前,需要在Kibana控制台的Dev Tools中开启插件配置。登录Kibana控制台的操作请参见通过Kibana连接集群

  • 开启插件

    KibanaDev Tools中执行以下命令,开启插件:

    PUT _cluster/settings
    {
      "transient": {
        "aliyun.sql.enabled": true
      }
    }
  • 关闭并卸载插件

    卸载aliyun-sql插件前,必须先关闭插件配置,否则卸载触发的集群重启会卡住。

    关闭插件配置:

    PUT _cluster/settings
    {
      "persistent": {
        "aliyun.sql.enabled": null
      }
    }

    如果未关闭插件配置就卸载了插件,导致重启卡住,执行以下命令清空归档配置恢复重启流程:

    PUT _cluster/settings
    {
      "persistent": {
        "archived.aliyun.sql.enabled": null
      }
    }

快速入门

以下示例通过写入测试数据并执行Join查询,演示aliyun-sql插件的基本用法。

aliyun-sql只支持查询类请求,不支持写入类请求,以下通过bulk API写入数据。

  1. 登录目标阿里云Elasticsearch实例的Kibana控制台。

    登录Kibana控制台的操作请参见通过Kibana连接集群

  2. KibanaDev Tools > Console 中,写入学生信息数据和排名数据。

    学生信息数据:

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

    学生排名数据:

    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"}
  3. 使用Join查询学生名称和排名。

    POST /_alisql
    {
      "query":"select stuinfo.name,sturank.sorder from stuinfo join sturank on stuinfo.id=sturank.id"
    }

    返回结果中,columns包含列名和类型,rows包含对应的行数据:

    {
      "columns" : [
        {
          "name" : "name",
          "type" : "text"
        },
        {
          "name" : "sorder",
          "type" : "text"
        }
      ],
      "rows" : [
        [
          "xiaoming",
          "5"
        ],
        [
          "xiaowang",
          "3"
        ],
        [
          "xiaoliu",
          "10"
        ]
      ]
    }

基础查询

所有SQL查询通过POST /_alisql端点执行。

  • 普通查询

    POST /_alisql?pretty
    {
      "query": "select * from monitor where host='100.80.xx.xx' limit 5"
    }
  • 指定返回结果条数

    POST /_alisql?pretty
    {
        "query": "select * from monitor",
        "fetch_size": 3
    }
  • 参数化查询

    POST /_alisql?pretty
    {
      "query": "select * from monitor where host= ? ",
      "params": [{"type":"STRING","value":"100.80.xx.xx"}],
      "fetch_size": 1
    }

请求参数

参数类型

参数名称

是否必须

示例

描述

URL参数

pretty

将返回结果格式化显示。

请求体参数

query

select * from monitor where host='100.80.xx.xx' limit 5

SQL查询语句。

请求体参数

fetch_size

3

每次查询的数据条数。默认值为1000,最大值为10000。超过10000时使用默认最大值10000。limit实现全量或范围查询,fetch_size类似游标查询

请求体参数

params

[{"type":"STRING","value":"100.80.xx.xx"}]

实现类似PreparedStatement的参数化查询功能。

返回结果

对于数据量较大的查询,首次执行SQL查询时,返回结果中包含的数据条数为fetch_size设置的值,并包含游标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****"
}

参数

说明

columns

包含nametype字段,表示查询字段的名称和类型。

rows

查询结果。

cursor

游标,用于翻页查询。

默认每次返回1000条数据。如果结果超过1000条,可持续使用游标查询获取剩余数据,直到返回结果中不再包含cursor或返回为空。

游标查询

通过上次查询返回的cursor值获取下一页数据。

  • 查询请求

    POST /_alisql?pretty
    {
        "cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****"
    }

    参数类型

    参数

    是否必须

    说明

    URL参数

    pretty

    将返回结果格式化显示。

    请求体参数

    cursor

    指定游标值,获取对应数据。

  • 返回结果

    {
      "rows": [
        [
          572547,
          3.327459E7,
          "100.80.xx.xx",
          "china-dd",
          "cpu",
          "2018-08-09T08:19:12.000Z"
        ]
      ],
      "cursor": "u5HzAgJzY0BEWEYxWlhKNVFXNWtS****"
    }

    返回结果与基础查询类似,但省略了columns字段以减少网络传输。

JSON格式查询

通过format=org参数以原始Elasticsearch JSON格式返回查询结果。此模式不支持Join查询。

  • 查询请求

    POST /_alisql?format=org
    {
      "query": "select * from monitor where host= ? ",
      "params": [{"type":"STRING","value":"100.80.xx.xx"}],
      "fetch_size": 1
    }

    其他查询参数与基础查询相同。

  • 返回结果

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

    返回结果格式与原始DSL查询相同,通过_scroll_id参数翻页。

translate查询

SQL语句转换为ElasticsearchDSL语句。此功能不支持Join查询。

  • 查询请求

    POST _alisql/translate
    {
      "query": "select * from monitor where host= '100.80.xx.xx' "
    }
  • 返回结果

    {
      "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查询

aliyun-sql插件的Join查询为Inner Join,底层通过Merge Join实现。使用时需注意以下限制:

  • Join字段必须随着Elasticsearch文档ID递增或递减。

  • Join字段仅支持数值类型,不支持字符串类型。

  • 单表最大查询数默认为10000条数据。

语法格式:

SELECT
  expression
FROM table_name
JOIN table_name
 ON expression
[WHERE condition]

通过集群动态参数max.join.size修改单表最大查询数,例如设置为20000:

PUT /_cluster/settings
{
  "transient": {
    "max.join.size": 20000
  }
}

nestedtext类型字段查询

aliyun-sql插件支持查询nestedtext类型的字段。

  1. 创建包含nestedtext字段的索引。

    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"
                            }
                        }
                    }
                }
            }
        }
    }
  2. 批量插入数据。

    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"}}
  3. 根据nested类型的second_name字段查询。

    POST _alisql
    {
      "query": "select * from user_info where name.second_name='Adams'"
    }

    返回结果:

    {
      "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"
        ]
      ]
    }
  4. 根据text类型的addr字段查询。

    POST _alisql
    {
      "query": "select * from user_info where addr='Bristol'"
    }

    返回结果:

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

自定义UDF函数

UDF只能在插件初始化时注册,不支持动态添加。以下以扩展date_format方法为例。

  1. 基于UDF,自定义DateFormat类。

    /**
     * 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);
        }
    
    }
  2. DateFormat类添加到插件初始化方法中。

    udfTable.add(KeplerSqlUserDefinedScalarFunction
                    .create("date_format"
                            , DateFormat.class
                            , (JavaTypeFactoryImpl) typeFactory));
  3. 使用UDF查询。

    select date_format(date_f,'yyyy') from date_test

SQL语法概览

基本查询语法

SELECT [DISTINCT] (* | expression) [[AS] alias] [, ...]
FROM table_name
[WHERE condition]
[GROUP BY expression [, ...]
 [HAVING condition]]
[ORDER BY expression [ ASC | DESC ] [, ...]]
[LIMIT [offset, ] size]

Join查询语法

SELECT
  expression
FROM table_name
JOIN table_name
 ON expression
[WHERE condition]

Function和表达式

类型

名称

示例

说明

Numeric Function

ABS

SELECT ABS(num_field) FROM table

返回指定数字的绝对值。

Numeric Function

ACOS

SELECT ACOS(num_field) FROM table

返回指定数字的反余弦值。

Numeric Function

ASIN

SELECT ASIN(num_field) FROM table

返回指定数字的反正弦值。

Numeric Function

ATAN

SELECT ATAN(num_field) FROM table

返回指定数字的反正切值。

Numeric Function

ATAN2

SELECT ATAN2(num_field1,num_field2) FROM table

返回两个指定数字的反正切值。

Numeric Function

CEIL

SELECT CEIL(num_field) FROM table

返回大于等于指定数字的最小整数值。

Numeric Function

CBRT

SELECT CBRT(num_field) FROM table

返回指定数字的双精度立方根值。

Numeric Function

COS

SELECT COS(num_field) FROM table

返回指定数字的余弦值。

Numeric Function

COT

SELECT COT(num_field) FROM table

返回指定数字的余切值。

Numeric Function

DEGREES

SELECT DEGREES(num_field) FROM table

将弧度值转换为度。

Numeric Function

EXPEXPM1

SELECT EXP(num_field) FROM table

返回e的指定数字的次方幂。

Numeric Function

FLOOR

SELECT FLOOR(num_field) FROM table

返回小于等于指定数字的最大整数值。

Numeric Function

SIN

SELECT SIN(num_field) FROM table

返回指定数字的正弦值。

Numeric Function

SINH

SELECT SINH(num_field) FROM table

返回指定数字的双曲正弦值。

Numeric Function

SQRT

SELECT SQRT(num_field) FROM table

返回指定数字的正平方根。

Numeric Function

TAN

SELECT TAN(num_field) FROM table

返回指定数字的三角正切值。

Numeric Function

ROUND

SELECT ROUND(num_field,2) FROM table

将指定数字四舍五入到指定的小数位。

Numeric Function

RADIANS

SELECT RADIANS (num_field) FROM table

将以度为单位的角度转换为以弧度为单位的近似等效角度。

Numeric Function

RAND

SELECT RAND() FROM table

返回一个带正号的双精度值,大于或等于0.0且小于1.0。

Numeric Function

LN

SELECT LN (num_field) FROM table

返回指定数字的自然对数。

Numeric Function

LOG10

SELECT LOG10 (num_field) FROM table

返回指定数字以10为底的自然对数。

Numeric Function

PI

SELECT PI() FROM table

返回PI的值。

Numeric Function

POWER

SELECT POWER (num_field,2) FROM table

返回指定数字的乘幂。

Numeric Function

TRUNCATE

SELECT TRUNCATE (num_field,2) FROM table

返回将指定数字截断到指定小数位的值。

Arithmetic Operate

+

SELECT (v1 + v2) as v FROM table

返回两个数字之和。

Arithmetic Operate

-

SELECT(v1 - v2) as v FROM table

返回两个数字之差。

Arithmetic Operate

*

SELECT(v1 * v2) as v FROM table

返回两个数字相乘的结果。

Arithmetic Operate

/

SELECT(v1 / v2) as v FROM table

返回两个数字相除的结果。

Arithmetic Operate

%

SELECT(v1 % v2) as v FROM table

返回两个数字相除后的余数。

Logic Operate

AND

SELECT * FROM table WHERE condition AND condition

返回将两种情况并运算后,查询的数据。

Logic Operate

OR

SELECT * FROM table WHERE condition OR condition

返回将两种情况或运算后,查询的数据。

Logic Operate

NOT

SELECT * FROM table WHERE NOT condition

返回排除某种情况的查询数据。

Logic Operate

IS NULL

SELECT * FROM table WHERE field IS NULL

返回当指定字段为空时的查询数据。

Logic Operate

IS NOT NULL

SELECT * FROM table WHERE field IS NOT NULL

返回当指定字段不为空时的查询数据。

String Function

ASCII

SELECT ASCII(str_field) FROM table

返回指定字符的ASCII值。

String Function

LCASELOWER

SELECT LCASE(str_field) FROM table

将指定字符串转换为小写。

String Function

UCASEUPPER

SELECT UCASE(str_field) FROM table

将指定字符串转换为大写。

String Function

CHAR_LENGTHCHARACTER_LENGTH

SELECT CHAR_LENGTH(str_field) FROM table

返回指定字符串的长度(以字节为单位)。

String Function

TRIM

SELECT TRIM(str_field) FROM table

从指定字符串中删除字首和字尾的空格。

String Function

SPACE

SELECT SPACE(num_field) FROM table

返回指定数量的空格字符的字符串。

String Function

LEFT

SELECT LEFT(str_field, 3) FROM table

从字符串中提取多个字符(从左开始)。

String Function

RIGHT

SELECT RIGHT(str_field, 3) FROM table

从字符串中提取多个字符(从右开始)。

String Function

REPEAT

SELECT REPEAT(str_field, 3) FROM table

返回一个新字符串,表示将原字符串重复指定次数。

String Function

REPLACE

SELECT REPLACE(str_field, "SQL", "HTML") FROM table

用新的子字符串替换字符串中所有出现的子字符串。

String Function

POSITION

SELECT POSITION("test" IN str_field) FROM table

返回子字符串在字符串中首次出现的位置。

String Function

REVERSE

SELECT REVERSE(str_test) from table

反转字符串并返回结果。

String Function

LPAD

SELECT LPAD(str_field, 20, "ABC") FROM table

从左边对字符串使用指定的字符进行填充,并指定填充之后字符串的长度。

String Function

CONCAT

SELECT CONCAT(str_field,'test') FROM table

将两个或多个表达式加在一起。

String Function

SUBSTRING

SELECT SUBSTRING(str_field, 5, 3) FROM table

从字符串中提取子字符串(从任何位置开始)。

Date Function

CURRENT_DATE

SELECT CURRENT_DATE() FROM table

返回当前日期。

Date Function

CURRENT_TIME

SELECT CURRENT_TIME() FROM table

返回当前时间。

Date Function

CURRENT_TIMESTAMP

SELECT CURRENT_TIMESTAMP() FROM table

返回当前日期和时间。

Date Function

DAYNAME

SELECT DAYNAME(date_field) FROM table

返回指定日期的工作日名称。

Date Function

DAYOFMONTH

SELECT DAYOFMONTH(date_field) FROM table

返回指定日期的月份。

Date Function

DAYOFYEAR

SELECT DAYOFYEAR(date_field) FROM table

返回指定日期的一年中的一天。

Date Function

DAYOFWEEK

SELECT DAYOFWEEK(date_field) FROM table

返回指定日期的星期的索引。

Date Function

HOUR

SELECT HOUR(date_field) FROM table

返回指定日期的小时部分。

Date Function

MINUTE

SELECT MINUTE(date_field) FROM table

返回指定时间或时间日期的分钟部分。

Date Function

SECOND

SELECT SECOND(date_field) FROM table

返回指定时间或时间日期的秒部分。

Date Function

YEAR

SELECT YEAR(date_field) FROM table

返回指定日期的年份部分。

Date Function

MONTH

SELECT MONTH(date_field) FROM table

返回指定日期的月份部分。

Date Function

WEEK

SELECT WEEK(date_field) FROM table

返回指定日期的星期数(1~54,MySQL的为0~53)。

Date Function

MONTHNAME

SELECT MONTHNAME(date_field) FROM table

返回指定日期的月份名称。

Date Function

LAST_DAY

SELECT LAST_DAY(date_field) FROM table

返回指定日期的所在月份的最后一天。

Date Function

QUARTER

SELECT QUARTER(date_field) FROM table

返回年份日期的季度值。

Date Function

EXTRACT

SELECT EXTRACT(MONTH FROM date_field) FROM table

返回指定日期或时间的单独部分,例如年、月、日、小时、分钟等。

Date Function

DATE_FORMAT

SELECT DATE_FORMAT(date_field,'yyyy') from date_test

将日期或时间数据格式化输出。

Aggregation Function

MIN

SELECT MIN(num_field) FROM table

返回一组值中的最小值。

Aggregation Function

MAX

SELECT MAX(num_field) FROM table

返回一组值中的最大值。

Aggregation Function

AVG

SELECT AVG(num_field) FROM table

返回一组值的平均值。

Aggregation Function

SUM

SELECT SUM(num_field) FROM table

返回一组值的总和。

Aggregation Function

COUNT

SELECT COUNT(num_field) FROM table

返回指定条件的记录数。

Advanced Function

CASE

SELECT * FROM table ORDER BY(CASE WHEN exp1 THEN exp2 ELSE exp3 END)

语法为CASE WHEN THEN ELSE END。当满足WHEN条件时返回THEN中的值,否则返回ELSE中的值(该值可以在SELECT、WHEREORDER中使用)。与IF THEN ELSE语法类似。