Elasticsearch(ES)中的腳本(Script)

文章目錄

  • 一. 腳本是什么?
    • 1. `lang`(腳本語言)
    • 2. `source`(腳本代碼)
    • 3. `params`(參數)
    • 4. `id`(存儲腳本的標識符)
    • 5. `stored`(是否為存儲腳本)
    • 6. `script` 的上下文(Context)
    • 7.完整示例
      • 內聯腳本(Inline Script)
      • 存儲腳本(Stored Script)
    • 8.字段總結表
  • 二. 腳本能做什么?
    • 1. 腳本查詢(Script Query)
    • 2. 腳本聚合(Script Aggregation)
    • 3. 更新文檔(Update By Script)
    • 4. 腳本排序(Script Sort)
    • 5. 腳本字段(Script Field)
    • 6. 索引時腳本(Ingest Pipeline)
    • 7. 腳本評分(Script Score Query)
    • 8. 數組操作(修改數組字段)
    • 關鍵點總結
  • 三. 為什么很多操作可以用腳本完成?
    • 1 靈活性
    • 2 避免冗余存儲
    • 3 批量操作效率
    • 4 擴展性
  • 四. 腳本類型與執行方式
    • 1 腳本語言
    • 2 執行上下文
    • 3 腳本存儲方式
  • 五. 安全與性能注意事項
    • 1 安全性
    • 2 性能優化
  • 六. 典型應用場景


一. 腳本是什么?

腳本是 ES 中一段可執行的代碼片段,通常用于在查詢或數據處理過程中動態計算值、修改文檔、實現復雜邏輯。ES 支持多種腳本語言,但默認推薦使用 Painless(ES 專門為性能和安全性設計的腳本語言)。

在 Elasticsearch 中,腳本(Script)的組成通常包括以下幾個核心字段,每個字段的作用和含義如下:


1. lang(腳本語言)

  • 含義:指定腳本使用的編程語言。

  • 默認值:painless(Elasticsearch 推薦的高性能腳本語言)。

  • 其他選項:expression(簡單表達式)、groovy(舊版本支持,需謹慎啟用)。

  • 示例:

    "script": {"lang": "painless","source": "..."
    }
    

2. source(腳本代碼)

  • 含義:腳本的具體邏輯代碼,用指定的 lang 語言編寫。

  • 作用:定義動態計算邏輯,例如字段操作、條件判斷、數學運算等。

  • 示例:

    "script": {"source": "doc['price'].value * params.discount"
    }
    

3. params(參數)

  • 含義:傳遞給腳本的外部參數,用于動態調整腳本行為。

  • 作用:避免硬編碼,提高腳本復用性。

  • 示例:

    "script": {"source": "doc['price'].value * params.discount","params": { "discount": 0.8 }
    }
    

4. id(存儲腳本的標識符)

  • 含義:引用預先存儲在 Elasticsearch 中的腳本(通過 _scripts API 存儲)。

  • 作用:避免重復編寫相同腳本,提升性能(預編譯)。

  • 示例:

    "script": {"id": "calculate_profit"
    }
    

5. stored(是否為存儲腳本)

  • 含義:標識腳本是否已存儲(通常與 id 配合使用)。

  • 示例:

    "script": {"stored": true,"id": "my_script"
    }
    

6. script 的上下文(Context)

雖然不是字段,但腳本的執行上下文決定了其行為,例如:

  • 查詢上下文:在 querybool 查詢中過濾或評分。
  • 聚合上下文:在 aggs 中生成計算字段。
  • 更新上下文:在 updateupdate_by_query 中修改文檔字段。

7.完整示例

內聯腳本(Inline Script)

{"query": {"script": {"script": {"lang": "painless","source": "doc['price'].value * params.discount > 100","params": { "discount": 0.8 }}}}
}
  • 字段解釋:
    • lang: 使用 Painless 語言。
    • source: 計算 price 字段乘以折扣后是否大于 100。
    • params: 傳遞折扣參數 0.8

存儲腳本(Stored Script)

  1. 存儲腳本:

    POST _scripts/calculate_profit
    {"script": {"lang": "painless","source": "doc['revenue'].value - doc['cost'].value"}
    }
    
  2. 調用存儲腳本:

    {"aggs": {"total_profit": {"sum": {"script": {"id": "calculate_profit"}}}}
    }
    

8.字段總結表

字段含義類型是否必需默認值
lang腳本語言Stringpainless
source腳本代碼邏輯String是(或 id-
params傳遞給腳本的參數Object{}
id存儲腳本的唯一標識符String-
stored是否引用存儲腳本Booleanfalse

二. 腳本能做什么?

腳本幾乎可以覆蓋 ES 的所有核心操作,常見用途包括:

以下是一些 Elasticsearch 腳本的常見使用場景示例及其詳細說明:


1. 腳本查詢(Script Query)

場景:根據動態條件過濾文檔(如價格乘以折扣后大于 100)。

{"query": {"bool": {"must": {"script": {"script": {"lang": "painless","source": "doc['price'].value * params.discount > params.threshold","params": {"discount": 0.8,"threshold": 100}}}}}}
}

說明:

  • 使用 params 傳遞折扣率和閾值,避免硬編碼。
  • doc['price'] 直接訪問字段的數值類型(比 _source 更高效)。

2. 腳本聚合(Script Aggregation)

場景:按利潤(收入 - 成本)分組統計。

{"aggs": {"profit_groups": {"terms": {"script": {"lang": "painless","source": "doc['revenue'].value - doc['cost'].value"},"size": 10}}}
}

說明:

  • 通過腳本動態計算利潤字段,無需預先存儲該字段。
  • 使用 terms 聚合對利潤分桶統計。

3. 更新文檔(Update By Script)

場景:為符合條件的文檔增加瀏覽量(views 字段 +1)。

POST /index/_update_by_query
{"script": {"source": "ctx._source.views += params.increment","params": { "increment": 1 }},"query": { "term": { "user": "alice" } }
}

說明:

  • ctx._source 訪問文檔的原始內容。
  • 通過 params.increment 參數化增量值,避免硬編碼。

4. 腳本排序(Script Sort)

場景:根據動態權重(如點擊量乘以系數)排序。

{"sort": {"_script": {"type": "number","script": {"source": "doc['clicks'].value * params.weight","params": { "weight": 1.5 }},"order": "desc"}}
}

說明:

  • 使用 _script 自定義排序邏輯。
  • type 指定排序值的類型(如 numberstring)。

5. 腳本字段(Script Field)

場景:在查詢結果中添加一個動態計算的字段(如價格等級)。

{"query": { "match_all": {} },"script_fields": {"price_level": {"script": {"source": """if (doc['price'].value > 1000) {return 'high';} else {return 'low';}"""}}}
}

說明:

  • script_fields 在返回結果中添加一個臨時字段 price_level
  • 使用條件判斷(if-else)動態分類。

6. 索引時腳本(Ingest Pipeline)

場景:在數據寫入時自動添加時間戳字段。

PUT _ingest/pipeline/add_timestamp
{"description": "Add timestamp at ingest time","processors": [{"script": {"source": "ctx.timestamp = new Date().getTime()"}}]
}

說明:

  • 通過 Ingest Pipeline 在索引時執行腳本。
  • ctx 表示當前文檔的上下文,直接修改字段。

7. 腳本評分(Script Score Query)

場景:根據自定義邏輯影響文檔相關性評分(如按點擊量加分)。

{"query": {"script_score": {"query": { "match_all": {} },"script": {"source": "Math.log(1 + doc['clicks'].value) * params.boost","params": { "boost": 2 }}}}
}

說明:

  • script_score 結合數學函數(如對數)動態調整評分。
  • params.boost 控制權重參數。

8. 數組操作(修改數組字段)

場景:向文檔的 tags 數組中添加新標簽。

POST /index/_update/1
{"script": {"source": "ctx._source.tags.add(params.new_tag)","params": { "new_tag": "popular" }}
}

說明:

  • ctx._source.tags.add() 直接操作數組字段。
  • 使用 params 傳遞動態參數。

關鍵點總結

  1. 語法規范:

    • 使用 doc['field'] 訪問數值型字段(高效)。
    • 使用 ctx._source 訪問文檔原始內容(靈活但較慢)。
  2. 參數化:

    • 通過 params 傳遞動態值,避免腳本注入風險。
  3. 存儲腳本:

    • 頻繁使用的腳本應存儲(POST _scripts/<id>)以提升性能。
  4. 安全限制:

    • 默認啟用 Painless 沙箱,禁止文件/網絡操作。

三. 為什么很多操作可以用腳本完成?

1 靈活性

  • 動態邏輯:無需提前定義字段或索引結構,直接通過腳本實現復雜計算。
  • 條件處理:根據實時參數或文檔內容動態調整行為(如 if-else 判斷)。

2 避免冗余存儲

  • 按需計算:無需預先存儲所有可能的派生字段(如利潤、折扣價),在查詢時通過腳本實時計算。

3 批量操作效率

  • 原子性更新:通過腳本直接修改文檔字段,避免先獲取再更新的網絡開銷(如 update_by_query)。

4 擴展性

  • 自定義評分:在搜索時通過腳本影響文檔的相關性得分(如結合地理位置、用戶行為)。

四. 腳本類型與執行方式

1 腳本語言

  • Painless(默認,安全且高性能)
  • Expression(簡單數學表達式)
  • 其他(如 Groovy、JavaScript,但需謹慎啟用)

2 執行上下文

  • 查詢時腳本:在 queryaggs 中實時計算。
  • 索引時腳本:在文檔寫入時通過 ingest pipeline 處理數據。
  • 更新時腳本:在 updateupdate_by_query 中修改文檔。

3 腳本存儲方式

  • 內聯腳本:直接嵌入到請求中(簡單但重復使用時效率低)。

  • 存儲腳本:將腳本保存在 ES 中,通過 ID 調用(復用性強,提升性能):

    POST _scripts/calculate_profit
    {"script": {"lang": "painless","source": "doc['revenue'].value - doc['cost'].value"}
    }
    

五. 安全與性能注意事項

1 安全性

  • ES 默認啟用腳本沙箱機制,限制敏感操作(如文件讀寫、網絡訪問)。

  • 可通過 elasticsearch.yml 配置禁用或限制腳本類型:

    script.allowed_types: inline
    script.allowed_contexts: search, update
    

2 性能優化

  • 避免復雜計算:腳本在查詢時逐文檔執行,復雜邏輯可能導致延遲。
  • 使用存儲腳本:預編譯存儲的腳本減少解析開銷。
  • 限制字段訪問:通過 doc['field'](快速)而非 _source(慢)獲取字段值。

六. 典型應用場景

  • 電商搜索:根據用戶位置動態調整運費或顯示本地化價格。
  • 日志分析:實時解析日志字段并生成統計信息。
  • 風控系統:根據用戶行為實時計算風險評分。
  • 數據清洗:在索引前標準化或豐富數據(如拆分字段、添加時間戳)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78420.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78420.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78420.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

客戶聯絡中心能力與客戶匹配方式

在數字化時代&#xff0c;客戶聯絡中心作為企業與客戶溝通的核心樞紐&#xff0c;其服務能力與客戶需求的精準匹配至關重要。隨著客戶期望的不斷提升&#xff0c;傳統的“一刀切”服務模式已難以滿足個性化需求&#xff0c;如何通過智能化的手段實現服務能力與客戶的高效匹配&a…

深入理解網絡原理:UDP協議詳解

在計算機網絡中&#xff0c;數據的傳輸是通過各種協議實現的&#xff0c;其中用戶數據報協議&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;作為一種重要的傳輸層協議&#xff0c;廣泛應用于實時通信、視頻流、在線游戲等場景。本文將深入探討UDP協議的特性、…

vscode切換Python環境

跑深度學習項目通常需要切換python環境&#xff0c;下面介紹如何在vscode切換python環境&#xff1a; 1.點擊vscode界面左上角 2.在彈出框選擇對應kernel

【MCP Node.js SDK 全棧進階指南】中級篇(4):MCP錯誤處理與日志系統

前言 隨著MCP應用的規模和復雜性增長,錯誤處理與日志系統的重要性也日益凸顯。一個健壯的錯誤處理策略和高效的日志系統不僅可以幫助開發者快速定位和解決問題,還能提高應用的可靠性和可維護性。本文作為中級篇的第四篇,將深入探討MCP TypeScript-SDK中的錯誤處理與日志系統…

【Qt】文件

&#x1f308; 個人主頁&#xff1a;Zfox_ &#x1f525; 系列專欄&#xff1a;Qt 目錄 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 輸入輸出設備類 三&#xff1a;&#x1f525; 文件讀寫類 四&#xff1a;&#x1f525; 文件和目錄信息類 五&…

代碼隨想錄算法訓練營第五十八天 | 1.拓撲排序精講 2.dijkstra(樸素版)精講 卡碼網117.網站構建 卡碼網47.參加科學大會

1.拓撲排序精講 題目鏈接&#xff1a;117. 軟件構建 文章講解&#xff1a;代碼隨想錄 思路&#xff1a; 把有向無環圖進行線性排序的算法都可以叫做拓撲排序。 實現拓撲排序的算法有兩種&#xff1a;卡恩算法&#xff08;BFS&#xff09;和DFS&#xff0c;以下BFS的實現思…

Qt實現語言切換的完整方案

在Qt中實現語言動態切換需要以下幾個關鍵步驟&#xff0c;我將提供一個完整的實現方案&#xff1a; 一、準備工作 在代碼中使用tr()標記所有需要翻譯的字符串 cpp button->setText(tr("Submit")); 創建翻譯文件 在.pro文件中添加&#xff1a; qmake TRANSLATION…

面試中被問到mybatis與jdbc有什么區別怎么辦

1. 核心區別 維度JDBCMyBatis抽象層級底層API&#xff0c;直接操作數據庫高層持久層框架&#xff0c;封裝JDBC細節代碼量需要手動編寫大量樣板代碼&#xff08;連接、異常處理等&#xff09;通過配置和映射減少冗余代碼SQL管理SQL嵌入Java代碼&#xff0c;維護困難SQL與Java代…

用于協同顯著目標檢測的小組協作學習 2021 GCoNet(總結)

摘要 一 介紹 問題一&#xff1a;以往的研究嘗試利用相關圖像之間的一致性&#xff0c;通過探索不同的共享線索[12, 13, 14]或語義連接[15, 16, 17]&#xff0c;來助力圖像組內的共同顯著目標檢測&#xff08;CoSOD&#xff09;&#xff0c;什么意思&#xff1f; 一方面是探…

OpenCV 圖形API(62)特征檢測-----在圖像中查找最顯著的角點函數goodFeaturesToTrack()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 確定圖像上的強角點。 該函數在圖像或指定的圖像區域內找到最顯著的角點&#xff0c;如文獻[240]中所述。 函數使用 cornerMinEigenVal 或 cor…

MySQL引擎分類與選擇、SQL更新底層實現、分庫分表、讀寫分離、主從復制 - 面試實戰

MySQL引擎分類與選擇、SQL更新底層實現、分庫分表、讀寫分離、主從復制 - 面試實戰 故事背景&#xff1a; 今天&#xff0c;我們模擬一場互聯網大廠Java求職者的面試場景。面試官將針對MySQL的核心技術點進行提問&#xff0c;涵蓋MySQL引擎分類與選擇、SQL更新底層實現、分庫…

如何確保微型導軌的質量穩定?

微型導軌在精密機械中扮演著至關重要的角色&#xff0c;它們不僅影響設備的性能&#xff0c;還決定了產品的壽命。那么&#xff0c;如何通過一些關鍵步驟來提高微型導軌的穩定性呢&#xff1f; 1、嚴格篩選供應商&#xff1a;選擇具備高品質保證能力的供應商&#xff0c;確保原…

Golang編程拒絕類型不安全

簡介 在 Go 中&#xff0c;標準庫提供了多種容器類型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;這些容器默認是類型不安全的&#xff0c;即它們可以接受任何類型的值&#xff0c;這可能導致運行時錯誤。為了提升代碼的類型安全性和可維護性&am…

什么是 JSON?學習JSON有什么用?在springboot項目里如何實現JSON的序列化和反序列化?

作為一個學習Javaweb的新手&#xff0c;理解JSON的序列化和反序列化非常重要&#xff0c;因為它在現代Web開發&#xff0c;特別是Spring Boot中無處不在。 什么是 JSON&#xff1f; 首先&#xff0c;我們簡單了解一下JSON (JavaScript Object Notation)。 JSON 是一種輕量級的…

iOS/Android 使用 C++ 跨平臺模塊時的內存與生命周期管理

在移動應用開發領域,跨平臺開發已經成為一種不可忽視的趨勢。隨著智能手機市場的持續擴張,開發者需要同時滿足iOS和Android兩大主流平臺的需求,而這往往意味著重復的工作量和高昂的維護成本。跨平臺開發的目標在于通過一套代碼庫實現多平臺的支持,從而降低開發成本、加速產…

【AAudio】A2dp sink創建音頻軌道的源碼流程分析

一、AAudio概述 AAudio 是 Android 8.0(API 級別 26)引入的 C/C++ 原生音頻 API,專為需要低延遲、高性能音頻處理的應用設計,尤其適用于實時音頻應用(如音頻合成器、音樂制作工具、游戲音效等)。 1.1 主要特點 低延遲:通過減少音頻數據在內核與用戶空間之間的拷貝,直…

Spring中配置 Bean 的兩種方式:XML 配置 和 Java 配置類

在 Spring 框架中,配置 Bean 的方式主要有兩種:XML 配置 和 Java 配置類。這兩種方式都可以實現將對象注冊到 Spring 容器中,并通過依賴注入進行管理。本文將詳細介紹這兩種配置方式的步驟,并提供相應的代碼示例。 1. 使用 XML 配置的方式 步驟 創建 Spring 配置文件 創建…

海之淀攻略

家長要做的功課 家長可根據孩子情況&#xff0c;需要做好以下功課&#xff1a; 未讀小學的家長&#xff1a;了解小學小升初派位初中校額到校在讀小學的家長&#xff1a;了解小升初派位初中校額到校在讀初中的家長&#xff1a;了解初中校額到校 越是高年級的家長&#xff0c;…

BUUCTF-[GWCTF 2019]re3

[GWCTF 2019]re3 查殼&#xff0c;64位無殼 然后進去發現主函數也比較簡單&#xff0c;主要是一個長度校驗&#xff0c;然后有一個mprotect函數&#xff0c;說明應該又是Smc&#xff0c;然后我們用腳本還原sub_402219函數處的代碼 import idc addr0x00402219 size224 for …

sql server 開啟cdc報事務正在執行

今天開啟數據庫cdc 功能的時候提示&#xff1a;一個dbrole 的存儲過程&#xff0c;rolemember cdc db_ower, &#xff0c;有事務正在進行&#xff0c;執行失敗。 執行多次仍然如此&#xff0c;開啟cdc的存儲過程是sys.sp_cdc_enable_db;查詢了一下網絡&#xff0c;給出的方…