#### 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