ElasticSearch SQL介绍
Elasticsearch SQL是一个X-Pack组件,它允许针对Elasticsearch实时执行类似SQL的查询。无论使用REST接口,命令行还是JDBC,任何客户端都可以使用SQL 在Elasticsearch内部本机搜索和聚合数据 。可以将Elasticsearch SQL视为一种翻译器,它可以理解SQL和Elasticsearch,并可以利用Elasticsearch功能轻松地进行大规模实时读取和处理数据。
Elasticsearch SQL旨在为Elasticsearch提供强大而轻量级的SQL接口。
为什么选择Elasticsearch SQL?
- 本机集成
- Elasticsearch SQL是为Elasticsearch从头开始构建的。根据基础存储,针对相关节点有效执行每个查询。
- 没有外部零件
- 无需其他硬件,流程,运行时或库即可查询Elasticsearch;Elasticsearch SQL通过在 Elasticsearch集群中运行来消除多余的运动部件。
- 轻巧高效
- Elasticsearch SQL并未抽象化Elasticsearch及其搜索功能-相反,它包含并公开了SQL以允许以相同的声明性,简洁的方式实时进行适当的全文本搜索。
SQL 入门
1、准备数据
本例使用ES版本是7.6.1,准备数据如下:
1 POST /book/_bulk 2 3 {"index":{"_id": "1001"}} 4 {"id": 1001, "name": "Java编程思想", "author": "小红", "release_date": "2011-06-02", "page_count": 561} 5 {"index":{"_id": "1002"}} 6 {"id": 1002, "name": "Java数据结构和算法", "author": "小绿", "release_date": "1989-05-26", "page_count": 482} 7 {"index":{"_id": "1003"}} 8 {"id": 1003, "name": "JavaScript权威指南", "author": "小蓝", "release_date": "1965-06-01", "page_count": 604} 9 {"index":{"_id": "1004"}} 10 {"id": 1004, "name": "Java并发编程实践", "author": "小白", "release_date": "1975-06-01", "page_count": 704}
2、使用SQL REST API查询
1 POST /_sql?format=txt 2 { 3 "query": "SELECT * FROM book WHERE release_date < ‘2000-01-01‘" 4 }
效果如下:
3、使用SQL CLI查询
Elasticsearch附带了一个脚本,用于在其bin
目录中运行SQL CLI :
1)运行sql cli
命令(默认连接http://localhost:9200):./bin/elasticsearch-sql-cli
命令(指定连接url):./bin/elasticsearch-sql-cli http://some.server:9200
命令(指定连接url带认证):./bin/elasticsearch-sql-cli http://sql_user:strongpassword@some.server:9200
2、使用sql cli执行查询sql命令
查询sql:SELECT * FROM book WHERE page_count > 500 ORDER BY page_count DESC;
效果如下:
SQL和Elasticsearch映射概念
尽管SQL和Elasticsearch对于数据的组织方式(和不同的语义)使用不同的术语,但本质上它们的目的是相同的。
SQL | Elasticsearch | 描述 |
column | field | 在这两种情况下,数据都以最低级别存储在命名条目中,该条目具有多种数据类型,包含一个值。SQL将此类条目称为列,而Elasticsearch将其称为字段。请注意,在Elasticsearch中,一个字段可以包含多个相同类型的值(本质上是一个列表),而在SQL中,一列可以恰好包含一个所述类型的值。Elasticsearch SQL将尽最大努力保留SQL语义,并根据查询拒绝那些返回具有多个值的字段的查询。 |
row | document |
Column s和field s 本身不存在;它们是row 或的一部分document 。两者的语义略有不同:a row 趋于严格(并具有更多的强制性),而a document 趋于更加灵活或宽松(同时仍具有结构)。 |
table | index | 对其执行查询的目标,无论是SQL还是Elasticsearch。 |
schema | implicit | 在RDBMS中,schema 主要是表的命名空间,通常用作安全边界。Elasticsearch没有为其提供等效的概念。但是,启用安全性后,Elasticsearch会自动应用安全性强制措施,以便角色仅查看允许其访问的数据(在SQL行话中,其模式为)。 |
catalog or database | cluster instance | 在SQL中,catalog 或database 可互换使用,并表示一组模式,即多个表。在Elasticsearch中,可用的索引集被分组为一个cluster 。语义也有所不同。a database 本质上是另一个名称空间(可能对数据的存储方式有一定影响),而Elasticsearch cluster 是运行时实例,或者是一组至少一个Elasticsearch实例(通常是分布式运行)。实际上,这意味着,尽管在SQL中一个实例中可能具有多个目录,但在Elasticsearch中一个实例仅限于一个。 |
cluster |
cluster(federated) |
传统上,在SQL中,群集是指包含多个 尽管RDBMS往往只有一个正在运行的实例,但在单台机器(未分布)上,Elasticsearch却相反,默认情况下,它是分布的和多实例的。 此外,Elasticsearch 单个集群::通常在同一名称空间内运行的多个Elasticsearch实例通常跨计算机分布。多个集群::多个集群,每个集群都有自己的名称空间,并在联合设置中相互连接 |
SQL REST API
1、查询
1)普通查询,同上
1 POST /_sql?format=txt 2 { 3 "query": "SELECT * FROM book ORDER BY page_count DESC LIMIT 5" 4 }
2)匹配索引查询
1 POST /_sql?format=txt 2 3 { 4 "query": "SELECT * FROM \"boo*\" WHERE page_count > 500 ORDER BY page_count DESC" 5 }
注意:索引名需要用双引号(")引起来
2、响应格式
虽然文本格式对人类很有益,但计算机更喜欢结构化的东西。
Elasticsearch SQL可以以下格式返回数据,可以通过format
URL中的属性或通过设置Accept
HTTP标头来设置数据:
json格式如下:
3、分页
当数据量较大时,需要分页返回,ES提供了游标的形式来分页
示例
1)第一次请求,设置接收数据大小
1 POST /_sql?format=sql 2 3 { 4 "query": "SELECT * FROM book order by release_date", 5 "fetch_size" : 1 6 }
效果如下:
2)第二页,使用游标获取数据
POST /_sql?format=json { "cursor": "5/WuAwFaAXNARFhGMVpYSjVRVzVrUm1WMFkyZ0JBQUFBQUFBQUFESVdlbVJGWmtzMmVWVlRXRk4zZW1SSFdETTNhMDFrWnc9Pf////8PBQFmBmF1dGhvcgEGYXV0aG9yAQR0ZXh0AAAAAWYCaWQBAmlkAQRsb25nAAAAAWYEbmFtZQEEbmFtZQEEdGV4dAAAAAFmCnBhZ2VfY291bnQBCnBhZ2VfY291bnQBBGxvbmcAAAABZgxyZWxlYXNlX2RhdGUBDHJlbGVhc2VfZGF0ZQEIZGF0ZXRpbWUBAAABHw==" }
效果如下:
请注意,响应数据中,该columns
对象只是第一页的一部分。
cursor
结果未返回时,您已到达最后一页。像Elasticsearch的滚动一样,
SQL可以在Elasticsearch中保持状态以支持游标。与滚动不同,接收最后一页足以保证清除Elasticsearch状态。
3)清空cursor
示例
1 POST /_sql/close 2 { 3 "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f///w8=" 4 }
SQL 翻译 API
SQL Translate API接受JSON文档中的SQL,并将其转换为本地Elasticsearch查询。
例如:
1 POST /_sql/translate 2 3 { 4 "query": "SELECT * FROM book ORDER BY page_count DESC", 5 "fetch_size": 10 6 }
效果如下:
翻译出来的DSL语句,可以用在Elasticsearch查询上