成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

查詢ElasticSearch:用SQL代替DSL

運維 數據庫運維
233醬工作中使用了一點ELK,偶爾使用Kibana拼接ES DSL簡直要命。如果你和我一樣「熟悉SQL,但不咋會寫DSL」 or 「想要用SQL簡化查詢」,本文會介紹一下官方對ES SQL的支持,希望對你有所幫助~

 [[344281]]

233醬工作中使用了一點ELK,偶爾使用Kibana拼接ES DSL簡直要命。如果你和我一樣「熟悉SQL,但不咋會寫DSL」 or 「想要用SQL簡化查詢」,本文會介紹一下官方對ES SQL的支持,希望對你有所幫助~

ES7.x版本的x-pack自帶ElasticSearch SQL,我們可以直接通過SQL REST API、SQL CLI等方式使用SQL查詢。

SQL REST API

在Kibana Console中輸入:

  1. POST /_sql?format=txt 
  2.   "query""SELECT * FROM library ORDER BY page_count DESC LIMIT 5" 

將上述SQL替換為你自己的SQL語句,即可。返回格式如下:

  1.     author      |        name        |  page_count   | release_date 
  2. -----------------+--------------------+---------------+------------------------ 
  3. Peter F. Hamilton|Pandora's Star      |768            |2004-03-02T00:00:00.000Z 
  4. Vernor Vinge     |A Fire Upon the Deep|613            |1992-06-01T00:00:00.000Z 
  5. Frank Herbert    |Dune                |604            |1965-06-01T00:00:00.000Z 

SQL CLI

elasticsearch-sql-cli是安裝ES時bin目錄的一個腳本文件,也可單獨下載。我們在ES目錄運行

  1. ./bin/elasticsearch-sql-cli https://some.server:9200 

輸入sql即可查詢

  1. sql> SELECT * FROM library WHERE page_count > 500 ORDER BY page_count DESC
  2.      author      |        name        |  page_count   | release_date 
  3. -----------------+--------------------+---------------+--------------- 
  4. Peter F. Hamilton|Pandora's Star      |768            |1078185600000 
  5. Vernor Vinge     |A Fire Upon the Deep|613            |707356800000 
  6. Frank Herbert    |Dune                |604            |-144720000000 

SQL To DSL

在Kibana輸入:

  1. POST /_sql/translate 
  2.   "query""SELECT * FROM library ORDER BY page_count DESC"
  3.   "fetch_size": 10 

即可得到轉化后的DSL query:

  1.   "size": 10, 
  2.   "docvalue_fields": [ 
  3.     { 
  4.       "field""release_date"
  5.       "format""epoch_millis" 
  6.     } 
  7.   ], 
  8.   "_source": { 
  9.     "includes": [ 
  10.       "author"
  11.       "name"
  12.       "page_count" 
  13.     ], 
  14.     "excludes": [] 
  15.   }, 
  16.   "sort": [ 
  17.     { 
  18.       "page_count": { 
  19.         "order""desc"
  20.         "missing""_first"
  21.         "unmapped_type""short" 
  22.       } 
  23.     } 
  24.   ] 

因為查詢相關的語句已經生成,我們只需要在這個基礎上適當修改或不修改就可以愉快使用DSL了。

下面我們詳細介紹下ES SQL 支持的SQL語句 和 如何避免錯誤使用。

首先需要了解下ES SQL支持的SQL語句中,SQL術語和ES術語的對應關系:

ES SQL的語法支持大多遵循ANSI SQL標準,支持的SQL語句有DML查詢和部分DDL查詢。

DDL查詢如:DESCRIBE table,SHOW COLUMNS IN table略顯雞肋,我們主要看下對SELECT,Function的DML查詢支持。

SELECT

語法結構如下:

  1. SELECT [TOP [ count ] ] select_expr [, ...] 
  2. FROM table_name ] 
  3. WHERE condition ] 
  4. GROUP BY grouping_element [, ...] ] 
  5. HAVING condition] 
  6. ORDER BY expression [ ASC | DESC ] [, ...] ] 
  7. [ LIMIT [ count ] ] 
  8. [ PIVOT ( aggregation_expr FOR column IN ( value [ [ AS ] alias ] [, ...] ) ) ] 

表示從0-N個表中獲取行數據。SQL的執行順序為:

  1. 獲取所有 FROM中的關鍵詞,確定表名。
  2. 如果有WHERE條件,過濾掉所有不符合的行。
  3. 如果有GROUP BY條件,則分組聚合;如果有HAVING條件,則過濾聚合的結果。
  4. 上一步得到的結果經過select_expr運算,確定具體返回的數據。
  5. 如果有 ORDER BY條件,會對返回的數據排序。
  6. 如果有 LIMIT or TOP條件,會返回上一步結果的子集。

與常用的SQL有兩點不同,ES SQL 支持TOP [ count ]和PIVOT ( aggregation_expr FOR column IN ( value [ [ AS ] alias ] [, ...] ) )子句。

TOP [ count ] :如SELECT TOP 2 first_name FROM emp表示最多返回兩條數據,不可與LIMIT條件共用。

PIVOT子句會對其聚合條件得到的結果進行行轉列,進一步運算。這個我是沒用過,不做介紹。

FUNCTION

基于上面的SQL我們其實已經能有過濾,聚合,排序,分頁功能的SQL了。但是我們需要進一步了解ES SQL中FUNCTION的支持,才能寫出豐富的具有全文搜索,聚合,分組功能的SQL。

使用SHOW FUNCTIONS 可列舉出支持的函數名稱和所屬類型。

  1. SHOW FUNCTIONS; 
  2.  
  3.       name       |     type 
  4. -----------------+--------------- 
  5. AVG              |AGGREGATE 
  6. COUNT            |AGGREGATE 
  7. FIRST            |AGGREGATE 
  8. FIRST_VALUE      |AGGREGATE 
  9. LAST             |AGGREGATE 
  10. LAST_VALUE       |AGGREGATE 
  11. MAX              |AGGREGATE 
  12. MIN              |AGGREGATE 
  13. SUM              |AGGREGATE 
  14. ........ 

我們主要看下聚合,分組,全文搜索相關的常用函數。

全文匹配函數

MATCH:相當于DSL中的match and multi_match查詢。

  1. MATCH( 
  2.     field_exp,       --字段名稱 
  3.     constant_exp,       --字段的匹配值 
  4.     [, options])       --可選項 

使用舉例:

  1. SELECT author, name FROM library WHERE MATCH(author, 'frank'); 
  2.  
  3.     author     |       name 
  4. ---------------+------------------- 
  5. Frank Herbert  |Dune 
  6. Frank Herbert  |Dune Messiah 
  7. SELECT author, name, SCORE() FROM library WHERE MATCH('author^2,name^5''frank dune'); 
  8.  
  9.     author     |       name        |    SCORE() 
  10. ---------------+-------------------+--------------- 
  11. Frank Herbert  |Dune               |11.443176 
  12. Frank Herbert  |Dune Messiah       |9.446629 

QUERY:相當于DSL中的 query_string 查詢。

  1. QUERY( 
  2.     constant_exp      --匹配值表達式 
  3.     [, options])       --可選項 

使用舉例:

  1. SELECT author, name, page_count, SCORE() FROM library WHERE QUERY('_exists_:"author" AND page_count:>200 AND (name:/star.*/ OR name:duna~)'); 
  2.  
  3.       author      |       name        |  page_count   |    SCORE() 
  4. ------------------+-------------------+---------------+--------------- 
  5. Frank Herbert     |Dune               |604            |3.7164764 
  6. Frank Herbert     |Dune Messiah       |331            |3.4169943 

SCORE():返回輸入數據和返回數據的相關度relevance.

使用舉例:

  1. SELECT SCORE(), * FROM library WHERE MATCH(name'dune'ORDER BY SCORE() DESC
  2.  
  3.     SCORE()    |    author     |       name        |  page_count   |    release_date 
  4. ---------------+---------------+-------------------+---------------+-------------------- 
  5. 2.2886353      |Frank Herbert  |Dune               |604            |1965-06-01T00:00:00Z 
  6. 1.8893257      |Frank Herbert  |Dune Messiah       |331            |1969-10-15T00:00:00Z 

聚合函數

AVG(numeric_field) :計算數字類型的字段的平均值。

  1. SELECT AVG(salary) AS avg FROM emp; 

COUNT(expression):返回輸入數據的總數,包括COUNT()時field_name對應的值為null的數據。

COUNT(ALL field_name):返回輸入數據的總數,不包括field_name對應的值為null的數據。

COUNT(DISTINCT field_name):返回輸入數據中field_name對應的值不為null的總數。

SUM(field_name):返回輸入數據中數字字段field_name對應的值的總和。

MIN(field_name):返回輸入數據中數字字段field_name對應的值的最小值。

MAX(field_name):返回輸入數據中數字字段field_name對應的值的最大值。

分組函數

這里的分組函數是對應DSL中的bucket分組。

HISTOGRAM:語法如下:

  1. HISTOGRAM( 
  2.            numeric_exp,    --數字表達式,通常是一個field_name 
  3.            numeric_interval    --數字的區間值 
  4.  
  5. HISTOGRAM( 
  6.            date_exp,      --date/time表達式,通常是一個field_name 
  7.            date_time_interval      --date/time的區間值 

如下返回每年1月1號凌晨出生的數據:

  1. ELECT HISTOGRAM(birth_date, INTERVAL 1 YEARAS h, COUNT(*) AS c FROM emp GROUP BY h; 
  2.  
  3.  
  4.            h            |       c 
  5. ------------------------+--------------- 
  6. null                    |10 
  7. 1952-01-01T00:00:00.000Z|8 
  8. 1953-01-01T00:00:00.000Z|11 
  9. 1954-01-01T00:00:00.000Z|8 
  10. 1955-01-01T00:00:00.000Z|4 
  11. 1956-01-01T00:00:00.000Z|5 
  12. 1957-01-01T00:00:00.000Z|4 
  13. 1958-01-01T00:00:00.000Z|7 
  14. 1959-01-01T00:00:00.000Z|9 
  15. 1960-01-01T00:00:00.000Z|8 
  16. 1961-01-01T00:00:00.000Z|8 
  17. 1962-01-01T00:00:00.000Z|6 
  18. 1963-01-01T00:00:00.000Z|7 
  19. 1964-01-01T00:00:00.000Z|4 
  20. 1965-01-01T00:00:00.000Z|1 

ES SQL局限性

因為ES SQL和ES DSL在功能上并非完全匹配,官方文檔提到的SQL局限性有:

大的查詢可能拋ParsingException

在解析階段,極大的查詢會占用過多的內存,在這種情況下,Elasticsearch SQL引擎將中止解析并拋出錯誤。

nested類型字段的表示方法

SQL中不支持nested類型的字段,只能使用

  1. [nested_field_name].[sub_field_name] 

這種形式來引用內嵌子字段。

使用舉例:

  1. SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages; 

nested類型字段不能用在where 和 order by 的Scalar函數上

如以下SQL都是錯誤的

  1. SELECT * FROM test_emp WHERE LENGTH(dep.dep_name.keyword) > 5; 
  2.  
  3. SELECT * FROM test_emp ORDER BY YEAR(dep.start_date); 

不支持多個nested字段的同時查詢

如嵌套字段nested_A和nested_B無法同時使用。

nested內層字段分頁限制

當分頁查詢有nested字段時,分頁結果可能不正確。這是因為:ES中的分頁查詢發生在Root nested document上,而不是它的內層字段上。

keyword類型的字段不支持normalizer

不支持數組類型的字段

這是因為在SQL中一個field只對應一個值,這種情況下我們可以使用上面介紹的 SQL To DSL的API 轉化為DSL語句,用DSL查詢就好了。

聚合排序的限制

  • 排序字段必須是聚合桶中的字段,ES SQL CLI突破了這種限制,但上限不能超過512行,否則在sorting階段會拋異常。推薦搭配Limit子句使用,如:
  1. SELECT * FROM test GROUP BY age ORDER BY COUNT(*) LIMIT 100; 

聚合排序的排序條件不支持Scalar函數或者簡單的操作符運算。聚合后的復雜字段(比如包含聚合函數)也是不能用在排序條件上的。

以下是錯誤例子:

  1. SELECT age, ROUND(AVG(salary)) AS avg FROM test GROUP BY age ORDER BY avg
  2.  
  3. SELECT age, MAX(salary) - MIN(salary) AS diff FROM test GROUP BY age ORDER BY diff; 

子查詢的限制

子查詢中包含GROUP BY or HAVING 或者比SELECT X FROM (SELECT ...) WHERE [simple_condition]這種結構復雜,都是可能執行不成功的。

TIME 數據類型的字段不支持GROUP BY條件和HISTOGRAM函數

如以下查詢是錯誤的:

  1. SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME); 
  2.  
  3. SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h 

但是將TIME類型的字段包裝為Scalar函數返回是支持GROUP BY的,如:

  1. SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME)); 

返回字段的限制

如果一個字段不在source中存儲,是無法查詢到的。keyword, date, scaled_float, geo_point, geo_shape這些類型的字段不受這種限制,因為他們不是從_source中返回,而是從docvalue_fields中返回。

本文轉載自微信公眾號「 碼農知識點」,可以通過以下二維碼關注。轉載本文請聯系 碼農知識點公眾號。

 

責任編輯:武曉燕 來源: 碼農知識點
相關推薦

2022-12-30 09:12:55

查詢es搜索值

2020-12-02 08:31:47

Elasticsear

2023-06-13 08:00:57

ChatGPT語言模型

2023-10-29 09:11:03

DSL語法

2023-11-13 12:48:32

語言DSL

2011-08-24 11:22:38

SQL ServerUNION代替OR

2009-07-14 09:37:06

SQL Azure

2011-03-18 13:44:44

SQL

2019-08-16 10:47:19

戰場物聯網IOT

2021-06-29 06:39:21

Linuxdust命令du命令

2010-09-10 16:20:10

SQL函數

2010-09-07 09:45:48

SQL語句

2009-03-24 11:11:19

加速并行查詢SQL

2010-11-12 13:20:31

SQL Server

2011-10-31 13:58:32

API

2023-12-26 12:12:57

檢索調優Scripting場景

2012-09-26 14:03:09

sendmailmsmtp

2020-10-28 07:03:11

NodeSassDart Sass

2010-09-10 14:09:23

2021-06-24 16:07:36

Linuxfind命令fd命令
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品一区二 | 国产精品毛片无码 | 欧美在线激情 | 亚洲在线日韩 | 亚洲毛片 | 欧美国产中文字幕 | 久久综合色综合 | 免费一区二区三区在线视频 | 毛片一级黄色 | 午夜视频在线观看一区二区 | 国产99久久精品一区二区永久免费 | 国产成人综合在线 | 欧美久久久久 | 日韩人体在线 | 日韩久久精品 | 毛片一区二区三区 | 亚洲欧美激情网 | 自拍视频网站 | 国产精品www | 另类 综合 日韩 欧美 亚洲 | 9久久| 99久久精品免费看国产四区 | 日日噜 | 久久久国产一区二区三区 | 久久久999免费视频 999久久久久久久久6666 | 成人欧美一区二区三区黑人孕妇 | 久久久久国产精品一区二区 | 日本 欧美 国产 | 一级日批片 | 国产成人高清视频 | aaa级片| 国产目拍亚洲精品99久久精品 | 亚洲网址在线观看 | 精品国产一区二区三区久久狼黑人 | 天堂视频中文在线 | 一区二区三区四区免费在线观看 | 欧美日韩淫片 | 中文字幕一区在线观看视频 | 精品视频在线观看 | 欧美亚洲另类丝袜综合网动图 | 九九久久精品 |