es 3期 第27节-运用Script脚本实现复杂需求

1.Elasticsearch是数据库,不是普通的Java应用程序,传统数据库需要的硬件资源同样需要,提升性能最有效的就是升级硬件。

2.Elasticsearch是文档型数据库,不是关系型数据库,不具备严格的ACID事务特性,任何企图直接替代严格事务性场景的应用项目都会失败!!!

3.Elasticsearch原则上适合一切非事务性应用场景或能够容许一定的延迟的事务性场景;能最大限度的替代mongodb与传统关系型数据库

索引字段与属性都属于静态设置,若后期变更历史数据需要重建索引才可生效
对历史数据无效!!!!
一定要重建索引!!!!

1、Script概要介绍

Script概念

概念解释

ES的脚本类同传统数据库的UDF,可以自定义一些规则表达式,目的是满足日益复杂的应用需求

Greenplum,支持Python/R

应用便利

支持灵活多变的应用场景与需求如:字段数值乘以10倍数

参数

script,定义脚本查询入口

lang,定义脚本语言

source,定义脚本内容

id,脚本编号名称,预定义脚本

params,定义脚本参数,全局参数

复制代码
# eg 乘以10
GET kibana_sample_data_flights/_search
{
  "query":{
    "match_all": {}
  },
  "script_fields":{
    "AvgTicketPrice_100":{
      "script":{
        "lang": "expression",
        "source": "doc['AvgTicketPrice']*10"
      }
    }
  }
}

Script脚本类型

脚本类型

1.Painless,最丰富的强大的脚本语言

2.Lucene,简洁高效的原生lucene脚本语言

3.Mustache,简洁高效的template脚本语言

4.Java,原生支持iava高级自定义的脚本语言

Script获取上下文数据值

获取上下文数据值

1.update script,数据更新上下文获取数据

2._score,数据分值

3.doc_value,从列式获取数据值

4._source,从原数据中获取数据值

5._store,从lucene存储中获取数据值

复制代码
# update script,eg 从Script获取数据,更新字段值
GET kibana_sample_data_flights_3share/_search
POST kibana_sample_data_flights_3share/_update_by_query
{
  "script":{
    "source": """
      ctx._source.FlightNum=ctx._source.OriginCountry + "_"+ctx._source.FlightNum
    """
  }
}
GET kibana_sample_data_flights_3share/_search

# _score,eg 从Script获取数据,修改分值
GET kibana_sample_data_flights_3share/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "Origin": "Newark"
        }
      },
      "script_score": {
        "script": {
          "lang": "expression",
          "source": "_score*doc['FlightTimeMin']"
        }
      }
    }
  }
}

# doc_value,eg 从Script获取数据,修改分值
GET kibana_sample_data_flights_3share/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "Origin": "Newark"
        }
      },
      "script_score": {
        "script": {
          "lang": "expression",
          "source": "doc['FlightTimeMin']*10"
        }
      }
    }
  }
}
# _source,eg 从Script获取数据,更新字段值
GET kibana_sample_data_flights_3share/_search
POST kibana_sample_data_flights_3share/_search
{
  "script_fields": {
    "FlightNum": {
      "script": {
        "lang": "painless",
        "source": "params._source.FlightNum+'_'+ params._source.OriginCityName"
      }
    }
  }
}

# _store, eg 从lucene-store中获取数据
# 创建索引时需要设定store=true,否则出错
PUT dev-001
{
  "mappings":{
    "properties":{
      "devName":{
        "type":"text",
        "store":true
      },
      "devDesc":{
        "type":"text",
        "store":true
      }
    }
  }
}
POST dev-001/_doc
{
  "devName":"设备名称-1",
  "devDesc":"设备描述内容"
}
GET dev-001/_search
{
  "stored_fields":["*"],
  "script_fields":{
    "devInfo":{
      "script":{
        "lang": "painless",
        "source": "params._fields['devName'].value+'_'+params._fields['devDesc'].value"
      }
    }
  }
}

脚本接口(扩展了解)

script_context

查询脚本执行支持的上下文参考

复制代码
GET _script_context

_script_language

查询内置已经注册脚本语言类型

内置脚本语言支持的上下文

复制代码
GET _script_language

scripts 创建

创建内置脚本,便于编译,提升执行能力

*PUT _scripts/<script-id>

*POST _scripts/<script-id>

*PUT _scripts/<script-id>/<context>

*POST _scripts/<script-id>/<context>

2、Lucene脚本应用

Lucene概要介绍

1.继承Lucene原生,简洁高效,表达能力有限

2.官方名称:expression

其它能力

1.性能最好

expression, eg

Lucene,继承原生lucene内置能力,性能好,简洁直接,性能同比其它,最好

查询参数

lang,定义查询语言类型

expression,lucene 语言类型

doc,获取参数

复制代码
# 获取日期的一天中的小时
GET kibana_sample_data_flights/_search
{
  "_source": [
    "timestamp"
  ],
  "track_total_hits": true,
  "script_fields": {
    "hourOfDay": {
      "script": {
        "lang": "expression",
        "source": "doc['timestamp'].date.hourOfDay"
      }
    }
  }
}
## 限制性条件
# 仅能获取数值、日期、geo_point类型

3、Mustache脚本应用

基于 Mustache 模板语法规则,简单适用

查询模板

复制代码
GET _search/template
{
  "source": {
    "query": {
      "match": {
        "{{my_field}}": "{{my_value}}"
      }
    },
    "size": "{{my_size}}"
  },
  "params": {
    "my_field": "message",
    "my_value":"foo",
    "my_size":10
  }
}

4、Painless脚本应用深入探查

概要介绍

1.基于自定义脚本规则,语言语法参考python/java,简洁高效,语言能力丰富。

2.Painless是编译模型,基于ANTLR4与ASM库编译

3.内置沙箱机制,非常安全

https://github.com/antlr/antlr4

https://zhuanlan.zhihu.com/p/575048391

查询参数

lang,定义查询语言类型

painless,查询语言

source,查询语言表达式

复制代码
# eg
GET kibana_sample_data_flights/_search
{
  "query":{
    "match_all": {}
  },
  "script_fields":{
    "AvgTicketPrice_100":{
      "script":{
        "lang": "expression",
        "source": "doc['AvgTicketPrice']*10"
      }
    }
  }
}

scripts/painless/_execute 测试接口

查询参数

POST /scripts/painless/execute

script,脚本表达式定义

context,上下文逻辑表达式

context_setup,上文参数,指定索引与字段替代等

test-context

默认测试上下文

测试自定义变量

复制代码
# eg 1
POST /_scripts/painless/_execute
{
  "script": {
    "source":"params.count/params.total",
    "params": {
      "count":11.0,
      "total":1100.0
    }
  }
}
  
# eg 2
POST /_scripts/painless/_execute
{
  "script": {
    "source":"""
    int i=10;
    float f=(float)i;
    float i_f=i*f;
    return i_f*params.p1;
    """,
    "params": {
      "p1": 100,
      "p2": 1000
    }
  }
}

filter-context

过滤上下文,查询逻辑表达式

bool 表达式

复制代码
# eg 
POST /_scripts/painless/_execute
{
  "script": {
    "source":"""
    int i=10;
    float f=(float)i;
    float i_f=i*f;
    float f1= i_f*params.p1;
    return f1<doc['AvgTicketPrice'].value;
    """,
    "params": {
      "p1": 100,
      "p2": 1000
    }
  },
  "context":"filter",
  "context_setup":{
    "index":"kibana_sample_data_flights",
    "document":{
      "AvgTicketPrice":100.11
    }
  }
}

score-context

数值上下文

复制代码
# eg 
POST /_scripts/painless/_execute
{
  "script": {
    "source":"""
    int i=10;
    float f=(float)i;
    float i_f=i*f;
    float f1= i_f*params.p1;
    return f1+doc['AvgTicketPrice'].value;
    """,
    "params": {
      "p1": 100,
      "p2": 1000
    }
  },
  "context":"score",
  "context_setup":{
    "index":"kibana_sample_data_flights",
    "document":{
      "AvgTicketPrice":100.11
    }
  }
}

限制性条件

性能限制

脚本语言越复杂,性能原则上越差

权限限制

脚本执行是在沙箱中进行,不能超过java 或者 es 权限限制边界,如禁止访问 IO 等

5、Java脚本应用自定义能力探查

当以上3种脚本无法满足特定诉求,可以基于java 语言自定义构造特殊的脚本,如需要突破IO 访问限制

或者与其它框架集成等

eg

1、编写java插件 ExpertScriptPlugin.java

参考官方案例

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/modules-scripting-engine.html

2、编译运行包

基于 gradle 构件程序包

jar包位置:elasticsearch-8.6.2\plugins\examples\script-expert-scoring\build\distrlbutions

3、复制到 Plugins 目录

例如我的目录是D:\Software\elasticsearch-8.6.2

进该目录下的plugins文件夹,这个文件夹默认是空的,在plugins下创建一个插件目录

将自己的jar复制进来

4、新增配置文件

新增配置文件plugin-descriptor.properties

#(可以在elasticsearch-8.6.2\modules\x-pack-async目录下拷一份过来改改)

重启es,通过_script_language查看支持的脚本,比原先多一个

GET _script_language

官方插件原代码位置

elasticsearch-8.6.2\plugins\examples\script-expert-scoring\src\main\java\org\elasticsearch\example\expertscript\ExpertScriptPlugin.java

6、Script应用场景

应用场景

脚本应用场景

查询:query

自定义字段:script_field

排序:sort

聚合:aggs

上卷:transform

分值:scrore

7、Script经验分享与总结

选择合适的脚本

注意脚本性能问题

scripting 脚本模块

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/modules-scripting.html

lucene-expressions 语法参考

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/modules-scripting-expression.html

lucene-expressions 官方参考

https://lucene.apache.org/core/8_8_2/expressions/index.html?org/apache/lucene/expressions/js/package-summary.html

painless 语言参考

https://www.elastic.co/guide/en/elasticsearch/painless/8.6/index.html

painless-execute-api 测试接囗

https://www.elastic.co/guide/en/elasticsearch/painless/8.6/painless-execute-api.html

search-template 查询模板

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/search-template.html

Java 脚本插件

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/modules-scripting-engine.html

script-apis 执行接口

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/script-apis.html

mapping-fields 索引元数据参考

https://www.elastic.co/guide/en/elasticsearch/reference/8.6/mapping-fields.html

相关推荐
星光璀璨山河无恙4 分钟前
【Hadoop】Hadoop3.1.4完全分布式集群搭建
大数据·hadoop·分布式
GIS数据转换器1 小时前
在机器人和无人机时代,测绘人的出路在哪里?
大数据·人工智能·信息可视化·机器人·自动驾驶·汽车·无人机
不辉放弃1 小时前
Spark 在 Python 大数据中的作用
大数据·python
Gvemis⁹2 小时前
Scala总结(二)
大数据·开发语言·scala
Elastic 中国社区官方博客3 小时前
Elasticsearch:使用 Azure AI 文档智能解析 PDF 文本和表格数据
大数据·人工智能·elasticsearch·搜索引擎·pdf·全文检索·azure
Lansonli5 小时前
大数据Spark(五十六):Spark生态模块与运行模式
大数据·分布式·spark
hf2000125 小时前
技术深度报道:解析云器Lakehouse如何实现超越Spark 10倍性能提升
大数据·分布式·spark
光仔December6 小时前
【Elasticsearch入门到落地】10、初始化RestClient
elasticsearch·搜索引擎·全文检索·ik分词器·restclient
不辉放弃9 小时前
Flink/Kafka在python中的用处
大数据·python
薇晶晶9 小时前
虚拟机安装linux系统无法上网的解决方法
大数据