Elasticsearch Painless Script详解
文章目錄
- 1. Painless 簡介
- Painless 的用途
- 2. 參數(shù)
- 3. 首選參數(shù)
- 4. 簡短腳本形式
- 5. 通過 Painless 腳本訪問字段
- 6. 示例
- 6.1 案例 1:Script Processsor
- 6.2 案例 2:文檔更新計數(shù)
- 6.3 案例 3:搜索時的 Script 字段
- 6.4 Script :Inline v.s Stored
- 6.5 示例4
- 3. 緩存
1. Painless 簡介
自 ES 5.x 后引入,專門為 ES 設(shè)置,擴展了 Java 的語法
6.0 開始,ES 只支持 Painless。Grooby ,JavaScript 和 Python 都不在支持
Painless 支持所有的 Java 的數(shù)據(jù)類型及 Java API 子集
Painless Script 具備以下特性
- 高性能 、 安全
- 支持顯示類型或者動態(tài)定義類型
Painless 的用途
Painless 可以對文檔字段進行加工處理
- 更新或者刪除字段,處理數(shù)據(jù)聚合操作
- Script Field: 對返回的字段提前進行計算
- Function Score:對文檔的算分進行處理
在 Ingest Pipeline 中執(zhí)行腳本
在 Reindex API,Update By Query 時,對數(shù)據(jù)進行處理
- 腳本編寫的語言,默認為painless。
- 腳本本身可以指定為內(nèi)聯(lián)腳本的source或存儲腳本的id。
- 應(yīng)傳遞給腳本的任何命名參數(shù)。
2. 參數(shù)
lang
- 指定編寫腳本的語言,默認為painless。
source,id
- 指定腳本的來源,inline腳本是指定source,,存儲的腳本是指定的id,并從群集狀態(tài)中檢索(請參閱存儲的腳本)。
params
- 指定作為變量傳遞到腳本的任何命名參數(shù)。
3. 首選參數(shù)
Elasticsearch第一次看到一個新腳本,它會編譯它并將編譯后的版本存儲在緩存中,編譯可能是一個繁重的過程。
如果需要將變量傳遞給腳本,則應(yīng)將它們作為命名參數(shù)傳遞給腳本本身而不是硬編碼值,例如,如果你希望能夠?qū)⒆侄沃党艘圆煌某藬?shù),請不要將乘數(shù)硬編碼到腳本中:
"source": "doc['my_field'] * 2"相反,將其作為命名參數(shù)傳遞:
"source": "doc['my_field'] * multiplier","params": {"multiplier": 2}第一個版本每次乘數(shù)改變時都必須重新編譯,第二個版本只編譯一次。
如果你在很短的時間內(nèi)編譯了太多獨特的腳本,Elasticsearch將使用circuit_breaking_exception錯誤拒絕新的動態(tài)腳本。默認情況下,每分鐘將編譯最多15個內(nèi)聯(lián)腳本,你可以通過設(shè)置script.max_compilations_rate動態(tài)更改此設(shè)置。
4. 簡短腳本形式
可以使用簡短腳本形式來簡化,在簡短形式中,script由字符串而不是對象表示,該字符串包含腳本的源。
簡寫:
"script": "ctx._source.likes++"正常形式的相同腳本:
"script": {"source": "ctx._source.likes++"}5. 通過 Painless 腳本訪問字段
| Ingestion | ctx.field_name |
| Update | ctx._source.field_name |
| Search & Aggregation | doc[“field_name”] |
6. 示例
6.1 案例 1:Script Processsor
# 增加一個 Script Prcessor POST _ingest/pipeline/_simulate {"pipeline": {"description": "to split blog tags","processors": [{"split": {"field": "tags","separator": ","}},{"script": {"source": """if(ctx.containsKey("content")){ctx.content_length = ctx.content.length();}else{ctx.content_length=0;}"""}},{"set": {"field": "views","value": 0}}]},"docs": [{"_index": "index","_id": "id","_source": {"title": "Introducing big data......","tags": "hadoop,elasticsearch,spark","content": "You konw, for big data"}},{"_index": "index","_id": "idxx","_source": {"title": "Introducing cloud computering","tags": "openstack,k8s","content": "You konw, for cloud"}}] }6.2 案例 2:文檔更新計數(shù)
DELETE tech_blogs PUT tech_blogs/_doc/1 {"title":"Introducing big data......","tags":"hadoop,elasticsearch,spark","content":"You konw, for big data","views":0 }POST tech_blogs/_update/1 {"script": {"source": "ctx._source.views += params.new_views","params": {"new_views":100}} }# 查看views計數(shù) POST tech_blogs/_search6.3 案例 3:搜索時的 Script 字段
GET tech_blogs/_search {"script_fields": {"rnd_views": {"script": {"lang": "painless","source": """java.util.Random rnd = new Random();doc['views'].value+rnd.nextInt(1000);"""}}},"query": {"match_all": {}} }6.4 Script :Inline v.s Stored
#保存腳本在 Cluster State POST _scripts/update_views {"script":{"lang": "painless","source": "ctx._source.views += params.new_views"} }POST tech_blogs/_update/1 {"script": {"id": "update_views","params": {"new_views":1000}} }6.5 示例4
首先,在集群狀態(tài)下創(chuàng)建名為calculate-score的腳本:
POST _scripts/calculate-score {"script": {"lang": "painless","source": "Math.log(_score * 2) + params.my_modifier"} }可以使用以下命令檢索相同的腳本:
GET _scripts/calculate-score可以通過指定id參數(shù)來使用存儲的腳本,如下所示:
GET _search {"query": {"script": {"script": {"id": "calculate-score","params": {"my_modifier": 2}}}} }刪除:
DELETE _scripts/calculate-score3. 緩存
編譯的開銷相較大
Elasticsearch 會將腳本編譯后緩存在 Cache 中
- Inline scripts 和 Stored Scripts 都會被緩存
- 默認緩存 100 個腳本
總結(jié)
以上是生活随笔為你收集整理的Elasticsearch Painless Script详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GLSL学习教程博客
- 下一篇: Hbase Region in tra