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分組排序即可解決。
查詢時,注意將兩側集群切換一致,否則查詢出錯:
- 關於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