es 按照日期字段,統計每天總數


SELECT count(*) FROM share_lhy_violation GROUP BY date_histogram(field='wfsj_date','interval'='1d','alias'='wfsj', 'format'='yyyy-MM-dd', 'time_zone'='+08:00', 'min_doc_count'=1,order='desc')

可用間隔如下:

1y

INTERVAL 1 YEAR

2M

INTERVAL 2 MONTH

3w

INTERVAL 21 DAY

4d

INTERVAL 4 DAY

5h

INTERVAL 5 HOUR

6m

INTERVAL 6 MINUTE

7s

INTERVAL 7 SECOND

以下轉自:https://www.cnblogs.com/wlzhang/p/11039312.html

ES SQL使用說明文檔

一、Elasticsearch術語介紹
l  接近實時(NRT):

Elasticsearch 是一個接近實時的搜索平台。這意味着,從索引一個文檔直到這個文檔能夠被搜索到有一個很小的延遲,包括如果做了集群的話,集群中的各個節點數據同步也是接近實時的。

l  集群(cluster):

一組擁有共同的 cluster name 的節點。

l  節點(node):

集群中的一個 Elasticearch 實例。

l  索引(index):

ElasticSearch將它的數據存儲在一個或多個索引(index)中。用SQL領域的術語來類比,索引就像數據庫,可以向索引寫入文檔或者從索引中讀取文檔。

l  文檔類型(type):

文檔類型(type)是用來規定文檔的各個字段內容的數據類型和其他的一些約束,相當於關系型數據庫中的表,一個索引(index)可以有多個文檔類型(type)。

l  文檔(document):

一個文檔(document)相當於關系型數據庫中的一行數據。

l  字段(Field):

相當於數據庫中的column。

l  映射(Mapping):

相當於數據庫中的schema,用來約束字段的類型,映射可以被明確地定義,或者在一個文檔被索引的時候自動生成。

l  分片(Shard):

索引的子集,索引可以切分成多個分片,分布到不同的集群節點上。分片對應的是 Lucene 中的索引。分片分為主分片(Primary shard)和副本分片(Replica shard)每個主分片可以有0個或者多個副本。

Elasticsearch與關系數據的類比對應關系如下:

Relational DB -> Databases -> Tables -> Rows -> Columns

關系型數據庫  數據庫     表      行     列

Elasticsearch -> Indices  ->  Types -> Documents -> Fields

Elasticsearch   索引       類型     文檔      域(字段)

由於Elasticsearch的查詢語言(DSL)比較復雜,學習成本高。因此推薦使用第三方插件Elasticsearch-SQL,可用sql查詢Elasticsearch,語法跟關系型數據庫的sql有一些不同。

注意:使用Elasticsearch-SQL查詢時:

1、在hue中查詢時,select前不能有空格或者空行;

2、查詢中字段名大小寫敏感;

3、求個數時,不能用 count(1), 必須是count(*);

4、select 字段名,* from….時  后面的*不起作用;

5、目前支持中文字段查詢,但不支持帶特殊符號的字段作為where條件,例如不支持where 總訂單數(條)>20;

6、兩個整數類型字段相除時,得到的結果也是整數,此時至少一個字段需要化為小數(例如乘除1.0、加減0.0):

SELECT 慢充終端數,快充終端數,1.0*慢充終端數/快充終端數 as a

from etlddcharging

where 快充終端數>0 and 慢充終端數>0 limit 10

二、快速入門:
ES查詢默認查詢200條,最大查詢10000條,可通過max_result_window修改。

1、查詢index下的type:

SELECT fields from indexName WHERE conditions

SELECT fields from indexName/type WHERE conditions

SELECT fields from indexName/type1,indexName/type2 WHERE conditions

SELECT fields from indexName1,indexName2 WHERE conditions

--其中,fields前面不能使用別名或者table.:

select color,doubleValue from cars,test_wj limit 10 (正確)

select cars.color,test_wj.doubleValue from cars,test_wj limit 10 (錯誤)

2、使用別名:

ES-Sql字段支持使用別名,當select后面只有一個別名列,查詢結果會列出所有的字段以及別名列,例如:

SELECT CityName as acity FROM mrp_userlabel LIMIT 10 ;

此時,若只想顯示別名列,有兩種解決方案:

l  使用exclude(*)排除其他列:

SELECT CityName as acity ,exclude(*) FROM mrp_userlabel LIMIT 10 ;

l  select后面添加一個非別名列,這相當於自動加了include,使結果只包含選擇的列名:

SELECT CityCode,CityName as acity FROM mrp_userlabel LIMIT 10 ;

3、分頁查詢:

SELECT * from mrp_userlabel limit 10,20

其中limit后面第一個參數是from,表示目標數據的偏移值,第二個參數是size,表示數據條數。以上查詢第10到第30條數據[l1] 。但是ES最大查詢默認max_result_window =10000條,當 from + size > max_result_window 時,es 將返回錯誤。

4、計算列--可以加減乘除固定數值,也可以兩個字段之間進行加減乘除:

SELECT CharPower,CharMoneyEC,CharMoneySC,

CharPower + 2 as a,

CharPower - 2 as b,

CharPower * 2 as c,

CharPower / 2 as d,

CharPower % 2 as e,

CharMoneyEC + CharMoneySC as f,

CharMoneyEC - CharMoneySC as g,

CharMoneyEC * CharMoneySC as h,

CharMoneyEC / CharMoneySC as i,

CharMoneyEC % CharMoneySC as j

from mrp_userlabel where CityCode<>'11' limit 10

注意:兩個整數類型字段相除時,得到的結果也是整數,此時至少一個字段需要化為小數(例如乘除1.0、加減0.0):

SELECT 慢充終端數,快充終端數,

1.0*慢充終端數/快充終端數 as a,慢充終端數/快充終端數 as b

from etlddcharging

where 快充終端數>0 and 慢充終端數>0 limit 10

5、數字范圍過濾--大於等於小於運算:

l  字段跟固定數值之間的運算:

SELECT *

from mrp_userlabel

where  CharPower > 0.9 and CharPower < 2.1 and CityName='北京市'

limit 10;

l  字段之間的運算1:【此時where后面只能跟一個條件,多了會報錯】

解決方案:

SELECT CharMoney,CharMoneySC,CharPower FROM mrp_userlabel where script('doc["CharMoney"].value>doc["CharMoneySC"].value && doc["CharPower"].value>0.9')

limit 10;

或者

SELECT CharMoney,CharMoneySC,CharPower FROM mrp_userlabel where script('doc["CharMoney"].value>doc["CharMoneySC"].value') and CharPower > 0.9

limit 10;

-- script語法詳見【6.1 Script基本用法:】

l  字段之間的運算2:【以下不支持】

解決方案:

SELECT CharMoney,CharMoneySC FROM mrp_userlabel where script('doc["CharMoney"].value+doc["CharMoneySC"].value>20')

limit 10 -- script語法詳見【6.1 Script基本用法:】

6、查詢日期字段:

見【3.2 函數支持】,使用date_format函數,支持傳遞時區。

7、group by分組,詳情見【3.3 聚合】:

l  group by 一個字段:

SELECT COUNT(*) FROM mrp_userlabel GROUP BY CityName;

l  group by多個字段且使用limit時,需要使用terms(原因見【3.3.2.1 terms聚合】):

SELECT COUNT(*) FROM mrp_userlabel

GROUP BY terms(field='CityName',size='10000',alias='CityName'),

terms(field='MarketName',size='10000',alias='MarketName')

limit 10000;

l  按照日期分組,使用date_histogram聚合,可以指定日期格式以及時區(具體用法見【3.3.2.3 日期直方圖(date histogram)聚合】):

SELECT count(*) FROM ChargeBillWideTable GROUP BY date_histogram(field='BeginTime','interval'='1d','alias'='yourAlias', 'format'='yyyy-MM-dd', 'time_zone'='+08:00', 'min_doc_count'=1,order='desc')

8、in或者not in用法:

某字段in一組值內時,in后面只能跟1024個值,超過會報錯,可用IN_TERMS[l2] 代替in:

SELECT MarketName,CityName,DataTime, CustID

FROM mrp_userlabel

WHERE DataTime='2018-10-31T16:00:00.000Z'

and MarketName ='青島特來電汽車充電有限公司'

and LabelLevel3 ='高價值用戶'

and not CustID = IN_TERMS(

SELECT  distinct CustID FROM mrp_userlabel

WHERE DataTime='2018-09-30T16:00:00.000Z'

and MarketName ='青島特來電汽車充電有限公司'

and LabelLevel3 ='高價值用戶'

limit 2000

)

ORDER BY MarketName asc,CityName asc,DataTime asc

LIMIT 10000;

三、基本用法
3.1. 基本查詢以及條件
l  基本查詢語法為:

SELECT fields from indexName WHERE conditions

l  查詢一個index下的type:

SELECT fields from indexName/type WHERE conditions

l  也可以一次性查詢一個index下的多個type:

SELECT fields from indexName/type1,indexName/type2 WHERE conditions

l  也可以一次性查詢多個index:

SELECT fields from indexName1,indexName2 WHERE conditions

--其中,fields前面不能使用別名或者table.:

select color,doubleValue from cars,test_wj limit 10 (正確)

select cars.color,test_wj.doubleValue from cars,test_wj limit 10 (錯誤)

3.1.1 SQL支持語句
SQL Select
SQL Delete(尚未開放)
SQL Where
SQL Order By
SQL Group By
SQL Limit (default is 200)
SELECT * FROM abnormalsoc_201801 WHERE PowerPerSoc > 0.9 LIMIT 10 ;

SELECT * FROM abnormalsoc_201801/abnormalsoc WHERE PowerPerSoc > 0.9 ORDER BY CanIndex DESC LIMIT 10 ;

SELECT * FROM abnormalsoc_201801 WHERE PowerPerSoc > 0.9 AND CtrlAddress = '42011700143' LIMIT 10 ;

3.1.2 SQL支持條件
SQL Like -(針對keyword類型字段,text類型字段不能使用like)
SQL AND & OR
SQL COUNT distinct
SQL In
SQL Between and
SQL Aliases
SQL NOT
SELECT count(distinct RelatedBillCode) FROM abnormalsoc_201801 where (CanIndex like '18%' or CanIndex like '19%') and CtrlAddress in ('42011700143','33011000371') limit 10;

SELECT * FROM test_wj where floatValue not Between 1.1 and 3.1 limit 10

--其中(Between 1.1 and 3.1)語法包括1.1、3.1。

3.1.3 SQL字段
字段可以按精確字段名稱列出,也可以用通配符(*)[l3] 使用include/exclude語法。

include('d ') - 包括以“d”開頭的所有字段
exclude('age') - 包括除“age”之外的所有字段
include('
Name'),exclude('lastName') - 包括以“name”結尾的所有字段,“lastName”除外。
SELECT CanIndex,include('Flink'),exclude('FlinkPorcessTimeTag')  FROM abnormalsoc_201801 LIMIT 10 ;

字段使用別名時:

ES-Sql字段支持使用別名,當select后面只有一個別名列,查詢結果會列出所有的字段以及別名列,例如:

SELECT CityName as acity FROM mrp_userlabel LIMIT 10 ;

此時,若只想顯示別名列,有兩種解決方案:

1)使用exclude(*)排除其他列:

SELECT CityName as acity ,exclude(*) FROM mrp_userlabel LIMIT 10 ;

2)select后面添加一個非別名列,這相當於自動加了include,使結果只包含選擇的列名:

SELECT CityCode,CityName as acity FROM mrp_userlabel LIMIT 10 ;

3.2 函數支持
支持以下函數:

l  Floor,向下取整;

l  Trim,刪除字符串首尾的空格;

l  Log,數學上的對數函數,計算一個數字的自然對數;

l  log10,數學上的對數函數;計算以10為基數的對數;

l  substring,截取字符串;

l  round,四舍五入為整數;

l  sqrt,一個非負實數的平方根;

l  concat_ws,根據分隔符連接字符串;

l  +  加、- 減、* 乘、/ 除、% 取余、>大於、<小於、=等於、<> 不等於;

l  case when;

l  cast,支持INT, LONG, FLOAT, DOUBLE, STRING, DATETIME;

l  date_format,日期格式化。

並且:

l  select,groupBy支持函數和字段使用別名;

l  支持嵌套函數,例如,Trim(substring('newtype',0,3));

l  支持二元操作,例如,floor(substring(newtype,0,14)/100)/5)*5。

date_format函數支持傳入時區參數(不傳時區,默認東八區),如下:

SELECT CreateTime, date_format(CreateTime,'yyyy-MM-dd HH') as aa, date_format(CreateTime,'yyyy-MM-dd HH','+0800') as bb, date_format(CreateTime,'yyyy-MM-dd HH','+0000') as cc

from datachangelog_201812 limit 10;

-- CreateTime是東八區時間,aa、bb是東八區時間,cc是UTC時間。

SELECT LastCharTime,date_format(LastCharTime,'yyyy-MM-dd HH') as aa,date_format(LastCharTime,'yyyy-MM-dd HH','+0800') as bb,date_format(LastCharTime,'yyyy-MM-dd HH','+0000') as cc from mrp_userlabel limit 10;

--LastCharTime是UTC時間,aa、bb取值是東八區時間,cc是UTC時間。

其他例子:

SELECT CityName,CharPower, trim(CityName) as a1,floor(CharPower) as a2,round(CharPower) as a3,sqrt(CharPower) as a4,log(CharPower) as a5,log10(CharPower) as a6

from mrp_userlabel;

SELECT CharPower,CharMoneyEC,CharMoneySC,

CharPower + 2 as a,

CharPower - 2 as b,

CharPower * 2 as c,

CharPower / 2 as d,

CharPower % 2 as e,

CharMoneyEC + CharMoneySC as f,

CharMoneyEC - CharMoneySC as g,

CharMoneyEC * CharMoneySC as h,

CharMoneyEC / CharMoneySC as i,

CharMoneyEC % CharMoneySC as j

from mrp_userlabel where CityCode<>'11' limit 10

SELECT MarketID,substring(MarketID,0,3) as aa,

CityCode,CityName,concat_ws(',',CityCode,CityName) as bb

from mrp_userlabel;

select CityCode,case when CityCode='11' then '北京市'  when CityCode='12'  then '天津市' else '其他' end as a

from  mrp_userlabel

limit 10

SELECT CityCode,DataTime, CAST(DataTime AS DATETIME) AS tt,cast(CityCode as INT)+1 as aa

from mrp_userlabel

limit 10;

3.3 聚合
3.3.1 Metrics(度量)
min
max
sum
count
avg
SELECT CanIndex,CtrlAddress, count(*),avg(PowerPerSoc), max(PowerPerSoc), min(PowerPerSoc),sum(PowerPerSoc)

FROM abnormalsoc_201801 group by CanIndex,CtrlAddress limit 10

stats(統計,查詢結果包含:sum、avg、max、min、count基礎度量):
percentiles(百分位數):
extended_stats(擴展統計,查詢結果包含:方差、平方和、標准差、標准差界限以及max、avg等基礎度量,注:只在數值型字段上使用):
SELECT stats(PowerPerSoc) FROM abnormalsoc_201801
SELECT percentiles(PowerPerSoc) FROM abnormalsoc_201801
SELECT extended_stats(PowerPerSoc) FROM abnormalsoc_201801
3.3.2 Buckets(桶)
3.3.2.1 terms聚合

l  group by一個字段:

SELECT COUNT(*) FROM mrp_userlabel GROUP BY CityName;

l  group by多個字段:

根據多個列進行group by時, select sum(x) from Table group by col1,col2 limit y 這種寫法會造成結果不正確,因為limit只會加在第一個字段上,后面的字段會按照默認值,每個桶(bucket)默認返回10條數據,例如:

SELECT COUNT(*) FROM mrp_userlabel GROUP BY CityName, MarketName limit 10000;

這樣所有的CityName,因為總數<10000,會被列出來,但每個CityName下最多返回10個MarketName,因為ES的默認桶返回值是10。解決方案為使用 group by terms()語法,正確寫法:

SELECT COUNT(*) FROM mrp_userlabel

GROUP BY terms(field='CityName',size='10000',alias='CityName'),

terms(field='MarketName',size='10000',alias='MarketName')

limit 10000;

3.3.2.2 范圍(range)聚合

字段后面跟上范圍。例如,查詢PowerPerSoc在0.5-1.0、1.0-2.0、2.0-3.0之間的數據條數:

SELECT COUNT(PowerPerSoc) FROM abnormalsoc_201801 GROUP BY range(PowerPerSoc, 0.5,1,2,3)

3.3.2.3 日期直方圖(date histogram)聚合

設置時間字段(field)、區間('interval')、可選是否使用別名('alias')、時間格式('format')、時區('time_zone')、桶內最大數據條數('min_doc_count')、排序(order):

SELECT count(*) FROM ChargeBillWideTable GROUP BY date_histogram(field='BeginTime','interval'='1d','alias'='yourAlias', 'format'='yyyy-MM-dd', 'time_zone'='+08:00', 'min_doc_count'=1,order='desc')

3.3.2.4 日期范圍(date range)聚合

設置字段以及帶格式的區間,可選是否使用別名。

SELECT count(*) FROM mrp_userlabel GROUP BY date_range('alias'='yourAlias',field='DataTime','format'='yyyy-MM-dd' ,'2018-10-21','2018-10-22','now-7d','now-6d','now')

3.4 Union and Minus
實現Union & Minus,第一個查詢字段名稱應該與第二個查詢字段名稱一致,可以使用別名。

3.4.1 Union(慎重使用)
將第一個表的查詢結果(不加limit,默認200條)跟第二個表的查詢結果組合在一起,發送給客戶端。

例子:

SELECT CityName FROM mrp_userlabel limit 1

union all

SELECT CityCode as CityName FROM mrp_userlabel limit 1

注:不建議,和分兩次取結果一樣,但效率會更慢。

3.4.2 Minus
3.4.2.1 基本實現

將第一個查詢結果作為一個集合(已刪除重復項),然后運行第二個查詢,檢查第二個查詢的每條數據是否已經存在於第一個查詢結果集中,若存在,則從集合中移除。最后返回集合。

例子:

一個字段:移除成都市的記錄:

SELECT  CityName FROM mrp_userlabel WHERE CityName in ('成都市','重慶市') limit 10

minus

SELECT  CityName FROM mrp_userlabel WHERE CityName in ('成都市') limit 10

2個字段(對比一整條記錄):還是會查出成都市的記錄:

SELECT  CityName, CityCode FROM mrp_userlabel WHERE CityName in ('成都市','重慶市') limit 10

minus

SELECT  CityName, CityName as CityCode FROM mrp_userlabel WHERE CityName in ('成都市') limit 10

3.4.2.2 scrolling 滾動

當第二個查詢數據量很大時,可使用scrolling 以提高性能。此時需要添加如下注釋:

/*! MINUS_SCROLL_FETCH_AND_RESULT_LIMITS(maxFetchOnFirstTable,maxFetchOnSecondTable,docsFetchFromShardOnEachScroll) */

例子:

SELECT /*! MINUS_SCROLL_FETCH_AND_RESULT_LIMITS(100000,10000000,5000) */
 CityName, CityCode FROM mrp_userlabel WHERE CityName in ('成都市','重慶市') limit 1000

minus

SELECT  CityName, CityName as CityCode FROM mrp_userlabel WHERE CityName in ('成都市') limit 1000

3.4.2.3 Scrolling and Terms 優化

當只Minus一個字段的時候,有效。當兩個查詢數據量都很大的時候,可使用此優化以保證較低的負載。需要添加如下注釋:

/*! MINUS_SCROLL_FETCH_AND_RESULT_LIMITS(maxFetchOnFirstTable,maxFetchOnSecondTable,docsFetchFromShardOnEachScroll) */

/! MINUS_USE_TERMS_OPTIMIZATION(true)/

例子:

SELECT /! MINUS_SCROLL_FETCH_AND_RESULT_LIMITS(100000,10000000,5000) /
/
! MINUS_USE_TERMS_OPTIMIZATION(true)
/

CityName FROM mrp_userlabel WHERE CityName in ('成都市','重慶市') limit 5000

minus

SELECT  CityName FROM mrp_userlabel WHERE CityName in ('成都市') limit 5000

四、擴展ES功能
增加了一些ES特有的擴展功能:

ES MISSING
ES STATS
ES EXTENDED_STATS
ES PERCENTILES
ES TERMS/TERM
ES IDS syntax: IDS_QUERY(type, ids..)
ES QUERY_STRING
1)查找mrp_userlabel中,字段CustName(不)為空的數據:

SELECT * FROM mrp_userlabel where CustName is not missing

SELECT * FROM mrp_userlabel where CustName is missing

--以上is missing相當於is null

2)某字段in一組值內時,in后面只能跟1024個值,超過會報錯,可用IN_TERMS[l4] 代替:

查找mrp_userlabel中,字段CityName(不)屬於成都市或合肥市或重慶市的數據:

SELECT * FROM mrp_userlabel where CityName = IN_TERMS('成都市','合肥市','重慶市')

SELECT * FROM mrp_userlabel where not CityName = IN_TERMS('成都市','合肥市','重慶市')

3)查找mrp_userlabel中,字段CityName等於成都市的數據:

SELECT * FROM mrp_userlabel where CityName = TERM('成都市')

SELECT * FROM mrp_userlabel where not CityName = TERM('成都市')

4)查找mrp_userlabel中,主鍵_id等於**的數據:

SELECT * FROM mrp_userlabel where _id = IDS_QUERY(mrp_userlabel, '66f5c013-1f10-4557-b473-e22ba7b2cc6d_20181022','2e171f39-6ea1-40b1-8494-b0141fcbcbb2_20181022')

5)查找mrp_userlabel中,字段MarketName等於*的數據:

SELECT * FROM mrp_userlabel where q = query('MarketName:濟南特來電新能源有限公司')

6)查找mrp_userlabel中,字段CustCode匹配正則表達式CD008.*的數據:

SELECT * FROM mrp_userlabel where CustCode = REGEXP_QUERY('CD008.*', 'INTERSECTION|COMPLEMENT|EMPTY', 10000)

五、注意事項
查詢語句末尾如果不加limit,則默認返回200條數據。Limit最大值為10000,經過特殊設置的索引除外;
聚合時,不支持字段加減運算后聚合以及聚合后加減運算:
sum(CharMoneySC+CharMoneyEC)以及sum(CharMoneySC)+sum(CharMoneyEC)。可使用script腳本實現:

select sum(script('aa','return doc["尖時電量"].value + doc["平時電量"].value;')) as Total from etlchargebills

where BillSrc='SD' and 充電日期>='20160101+08:00' and 充電日期<'20190201+08:00'

group by 充電日期 order by 充電日期 limit 100

普通排序:
1)order by默認方式為asc升序,如果order by多個字段,且每個字段都為desc排序,需要每個字段后面都加上desc;

2)有limit限制的,limit必須放在order by后面才能排序正確:

SELECT CharPower,CharMoney

FROM mrp_userlabel

order by CharPower desc, CharMoney desc

limit 10

以上sql先按照“CharPower” 降序排列,“CharPower”值相同的,再按照“CharMoney”降序排列。

聚合排序:
1)group by一個字段,order by多個字段:只能按照最后一個字段排序:

2)同樣的group by一個字段,order by后面跟一個維度+一個值的時候,排序只按照最后一個字段排序:

3)group by兩個字段時,由於ES聚合的分桶機制,導致排序不正確:

解決方案:可在ES索引中增加一個字段AA,值=CityCode+CityName,然后按照AA分組排序即可解決。

查詢時,注意將兩側集群切換一致,否則查詢出錯:

  1. 關於TopHits:

Sql雖然支持topHits寫法,但是topHits不起作用,實際返回結果並沒有具體值:

SELECT topHits('size'=2,floatValue='desc') FROM test_wj group by name limit 10;

原因在於elasticsearch-sql源碼中沒有解析聚合后的TopHits結果集:

但是可通過DSL查詢獲取相關TopHits的結果集:

六、附錄:
6.1 Script基本用法:
有時簡單的ES Sql語句無法支持某些查詢(如【二、快速入門】--【字段之間的運算1/2】),此時需要在sql語句中使用script語句。

前面已經說過,Elasticsearch的查詢語言是DSL,由於比較復雜,因此第三方開發了插件Elasticsearch-SQL。因此要介紹script在ES Sql中的用法,必須先了解script在DSL中的用法。語法如下:

"script": {

"lang":   "painless",

"source" | "id": "...",

"params": { ... }

}

腳本參數說明:

l  lang:指定編寫腳本的語言,默認為painless。

l  source,id:指定腳本的來源,inline腳本是指定source,如上例所示,存儲的腳本是指定的id,並從群集狀態中檢索(請參閱存儲的腳本)。

l  params:指定作為變量傳遞到腳本的任何命名參數。

painless是一種簡單,安全的腳本語言,專為與Elasticsearch一起使用而設計,它是Elasticsearch的默認腳本語言,可以安全地用於內聯和存儲腳本,有關painless語法和語言功能的詳細說明,請參閱:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-painless.html

以下主要分為Script Fields、Script Query來介紹:

6.1.1 Script Fields(查詢字段):
參考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html

GET test_wj/_search  

    "from": 0, 
    "size": 10, 
    "_source": { 
        "includes": [], 
        "excludes": [] 
    },  
    "script_fields": { 
10.         "aa": { 
11.             "script": { 
12.                 "source": "doc["floatValue"].value * 2", 
13.                 "lang": "painless" 
14.             },  
15.             "ignore_failure": false  
16.         }  
17.     }  
18. }

以上語句中計算字段floatValue*2的值,返回新字段aa。並使用doc關鍵字獲取字段值。Doc Values介紹如下:

在 Elasticsearch中,Doc Values就是一種列式存儲結構,默認情況下每個字段的Doc Values都是激活的,Doc Values是在索引時創建的,當字段索引時,Elasticsearch 為了能夠快速檢索,會把字段的值加入倒排索引中,同時它也會存儲該字段的“Doc Values”。

Elasticsearch 中的Doc Values常被應用到以下場景:

l  對一個字段進行排序;

l  對一個字段進行聚合;

l  某些過濾,比如地理位置過濾;

l  某些與字段相關的腳本計算。

6.1.2 Script Query(過濾條件):
參考:

https://www.elastic.co/guide/en/elasticsearch/reference/6.0/query-dsl-script-query.html

query過濾查詢可以使用script,並且用在filter context中:

GET test_wj/_search  

    "from": 0, 
    "size": 10, 
    "query": { 
      "bool": { 
        "must":{ 
          "script": { 
            "script": { 
10.               "source": "doc["floatValue"].value > 2 && doc["doubleValue"].value > doc["floatValue"].value", 
11.               "lang": "painless" 
12.               }  
13.            }  
14.          }  
15.         }  
16.     }  
17. }

以上語句查詢字段floatValue值大於2且doubleValue值大於floatValue值的數據。

6.1.3 Script 在 ES Sql中的用法:
Script在ES Sql中的用法也分為Script Fields、Script Query來介紹。

1、Script Field(查詢字段):

select script('aa','doc["floatValue"].value * 2') as aa1 from test_wj limit 10

可把script看為帶2個參數的函數,其中第一個參數'aa'相當於script_fields名稱,第二個參數相當於DSL語句中的script的source。以上sql相當於【6.1.1 Script Fields(查詢字段)】中的DSL語句。具體如下:

2、Script Query(過濾條件):

select * from test_wj where script('doc["floatValue"].value > 2 && doc["doubleValue"].value > doc["floatValue"].value') limit 10

可把script看為帶1個參數的函數,其中參數相當於DSL語句中的script的source。以上sql相當於【6.1.2 Script Query(過濾條件)】中的DSL語句。具體如下:

其他例子:

SELECT PhotoTime, script('ConvertedUptime','painless','def date_format_1606432247 = new SimpleDateFormat('yyyyMMdd').format(new Date(doc['PhotoTime'].value + 8100060*60));return date_format_1606432247;')  from vehiclephotopath_201812 limit 10

--注意,"script"的"source",有def定義字段或者函數時,必須有return返回值

SELECT sum(script('aa','return doc["floatValue"].value * 2;')) as aa1 from test_wj limit 10

--script也可用於sum等聚合統計

SELECT IndustryType,City, SumPower

from JZDS_StationRPT

WHERE script('def cc = ["北京市","青島市"];doc["IndustryType"].value != "公交" &&  cc.contains(doc["City"].value)')  and SumPower > 50

limit 100

select PileCanSN, cast(PileCanSN AS INT) as b

from  chargebillwidetable

where PileCanSN  <> '' and script('return Integer.parseInt(doc["PileCanSN"].value.toString()) > 180')

limit 10

--cast函數不能用在where條件后面,只能用在select后面

七、待辦:
1、聚合查詢,group by多字段后,必須用terms,此時無法支持分頁以及排序:

SELECT 電站名稱,  電站編號,電站ID,

sum(充電量) 充電電量,sum(訂單數) 充電次數

FROM etldaystasum

where 1=1 AND 業務日期='20190304+08:00'

group by terms(field='電站名稱',size='10000',alias='電站名稱'),terms(field='電站編號',size='10000',alias='電站編號'),terms(field='StaID',size='10000',alias='電站ID')

Order by  充電電量 desc

limit 10,20

以上sql中,limit from size方式分頁不起作用;order by排序也不起作用。

2、ES max聚合只能針對數值型字段,不能對string類似進行max聚合。

[l1]在Elasticsearch查詢結果集中,默認按照相關性進行排序,相關性越高,排名越靠前。相關性分值會用_score字段來給出一個浮點型的數值,所以默認情況下,結果集以_score進行倒序排列。

[l2]IN_TERMS只用於keyword類型字段。

IN_TERMS也有上限,默認65536,可以修改索引級別參數index.max_terms_count設置。此參數設置過大查詢會很慢而且會影響集群性能。

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

[l3]目前驗證只支持*通配符,不支持?、[]、{}等其他通配符

[l4]IN_TERMS只用於keyword類型字段。

IN_TERMS也有上限,默認65536,可以修改索引級別參數index.max_terms_count設置。此參數設置過大查詢會很慢而且會影響集群性能
————————————————
版權聲明:本文為CSDN博主「zwhfyy」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zwhfyy/java/article/details/100155564


免責聲明!

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



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