zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/ellafive/p/12794203.html
Copyright © 2011-2022 走看看