Elasticsearch SQL特性研究


Elasticsearch SQL特性研究

簡介

從Elasticsearch 發布以來,一直有自己的查詢語言(DSL),從6.3版本開始,Elasticsearch 開始支持SQL查詢語言。即6.3、6.4、6.5、6.6、6.7、7.0均支持SQL查詢。但是6.7之前SQL功能是實驗性質的,6.6進入beta特性列表,6.7后成為官方正式支持的特性。其中一些SQL相關的API變化較大,各版本間不兼容。SQL查詢是Elasticsearch XPack商用插件包中的功能,商用是需要收費的,目前jdbc Driver 只在鉑金級的產品上才能用。

概念對應

SQL Elasticsearch 對比說明
column field ES盡可能的把字段和SQL中的列做對應,並不是完全對應的上,比如ES中字段可能是一個list
row document document 結構更靈活和松散,row更嚴格
table index 查詢語句執行的對象,理論上table 和index 更加具有可比性,而不是type
schema 無對應關系 SQL中schema是一個table、index 等對象的命名空間,能起到一定的訪問控制的作用,ES中沒有合適的對應,或者對應上具有安全特性的ES的role概念
database或catalog cluster 實例 SQL中database和catalog大多數情況指的是一個概念,代表schema的集合。ES中cluster是index的集合
cluster cluster、集群聯盟 典型的SQL場景中,cluster指的是包含多個database或catalog的單個實例,ES的cluster是真正的運行在多個機器上的分布式節點集群

SQL查詢的方式

  • 使用PST _xpack/sql?format=txt 或者_sql?format=txt(7.0后)API
    • format 支持 txt ,以表格方式返回數據
    • format 支持josn ,以json格式返回數據
    • format支持其他格式,如csv、yaml、cbor、smile
  • 使用es命令行工具 /bin/elasticsearch-sql-cli
  • 使用jdbc Driver 或者odbc Driver (鉑金級產品才能用)

SQL查詢的本質

_sql API 本質上是一個翻譯者的角色,把SQL翻譯成了DSL語句給ES去執行,可以通過 /_xpack/sql/translate 查看翻譯后的DSL

POST /_xpack/sql/translate
{
    "query": "SELECT * FROM library ORDER BY page_count DESC",
    "fetch_size": 10
}

返回

{
    "size" : 10,
    "docvalue_fields" : [
        {
            "field": "page_count",
            "format": "use_field_mapping"
        },
        {
            "field": "release_date",
            "format": "epoch_millis"
        }
    ],
    "_source": {
        "includes": [
            "author",
            "name"
        ],
        "excludes": []
    },
    "sort" : [
        {
            "page_count" : {
                "order" : "desc",
                "missing" : "_first",
                "unmapped_type" : "short"
            }
        }
    ]
}

支持的SQL命令

  • SELECT
    只支持SELECT 查詢語句,且不是所有的SELECT 語法結構都支持,不支持INSERT、UPDATE、DELETE、CREATE等語句
curl -X POST -H 'Content-Type: application/json' -i http://localhost:9200/test2/_doc/2 --data '{
   "name":"wangzhen2",
    "info":{"sex":"man","age":28}
}'

查詢全部

curl -X POST -H 'Content-Type: application/json' -i 'http://localhost:9200/_xpack/sql?format=txt' --data '{
  "query":"select * from test2"
}'

返回數據

   info.age    |   info.sex    |     name      
---------------+---------------+---------------
28             |man            |wangzhen2      
28             |man            |wangzhen  
  • DESCRIBE/DESC/SHOW COLUMNS
    描述一個索引的定義,類似GET /{index}/{type}/_mappings ,查看該索引有多少字段,字段的類型。
curl -X POST -H 'Content-Type: application/json' -i 'http://localhost:9200/_xpack/sql?format=json' --data
'{
    "query": "desc library"
}'

返回

{
  "columns": [{
    "name": "column",
    "type": "keyword"
  }, {
    "name": "type",
    "type": "keyword"
  }, {
    "name": "mapping",
    "type": "keyword"
  }],
  "rows": [
    ["author", "VARCHAR", "text"],
    ["author.keyword", "VARCHAR", "keyword"],
    ["name", "VARCHAR", "text"],
    ["name.keyword", "VARCHAR", "keyword"],
    ["page_count", "BIGINT", "long"],
    ["release_date", "TIMESTAMP", "datetime"]
  ]
}
  • SHOW FUNCTIONS
    展示支持的SQL函數
curl -X POST -H 'Content-Type: application/json' -i 'http://localhost:9200/_xpack/sql?format=json' --data '{
    "query": "show functions"
}'

返回

{
  "columns": [{
    "name": "name",
    "type": "keyword"
  }, {
    "name": "type",
    "type": "keyword"
  }],
  "rows": [
    ["AVG", "AGGREGATE"],
    ["COUNT", "AGGREGATE"],
    ["FIRST", "AGGREGATE"],
    ...
    ]
 }
  • SHOW TABLES
    展示集群中的index 信息
curl -X POST -H 'Content-Type: application/json' -i 'http://localhost:9200/_xpack/sql?format=json' --data
 '{
    "query": "show tables"
}'

返回

{
  "columns": [{
    "name": "name",
    "type": "keyword"
  }, {
    "name": "type",
    "type": "keyword"
  }],
  "rows": [
    ["library", "BASE TABLE"],
    ["test", "BASE TABLE"],
    ["twitter", "BASE TABLE"]
  ]
}

SQL限制

  • nested 類型字段限制

    • DESC/SYSC_COLUMNS 不顯示字段內的定義
    • 在查詢中不能直接使用該字段,只能使用該字段的子字段
    • 同一個查詢中不能引用多個嵌套(nested)字段
    • 包含內嵌字段的分頁是不准確的,因為分頁是作用在根文檔上的,不是內嵌文檔
  • 數組字段限制

    • 如果一個字段是數組類型,且包含多個值,用REST接口查詢時會拋出異常(field.multi.value.leniency 參數默認是false)
    • 如果一個字段是數組類型,且包含多個值,用JDBC Driver查詢時會返回第一個值,但是值的順序不能保證(field.multi.value.leniency 參數默認是true)
  • 聚合限制

    • 聚合排序(group by a order by b)只能對前512個結果排序,超過這個大小的結果會拋出異常,推薦用limit 限制結果結合大小
    • 聚合函數如 sum、max、mix 只能直接使用在字段上,不能嵌套使用,如SELECT MAX(abs(age)) FROM test
  • 子查詢限制

    • 只能支持簡單的子查詢(比如,這個子查詢實際上可以扁平化改寫成一個不包含子查詢的SELECT 語句)
    • 不支持復雜的子查詢
    • 不支持子查詢里帶有 group by 或者having
  • 不支持在Having 子語句中使用First 或者 Last


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM