最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Elasticsearch8.1中的Script使用實例深入解讀

 更新時間:2023年10月29日 09:46:44   作者:醉魚  
這篇文章主要為大家介紹了Elasticsearch8.1中的Script使用實例深入解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、什么是 Elasticsearch Script?

Elasticsearch 中的 Script 是一種靈活的方式,允許用戶在查詢、聚合和更新文檔時執(zhí)行自定義的腳本。這些腳本可以用來動態(tài)計算字段值、修改查詢行為、執(zhí)行復(fù)雜的條件邏輯等等。

二、支持的腳本語言有哪些

支持多種腳本語言,包括 Painless、Expression、MustacheJava等,其中默認(rèn)的是Painless。

三、Painless 腳本的使用

Painless 是一種專為 Elasticsearch 設(shè)計的腳本語言,具有安全、快速、簡單的特點,使其在 Elasticsearch 中非常方便入門。

  • 安全性: Painless 被設(shè)計為一種安全的腳本語言。它采取了一系列的安全措施,如禁止無限循環(huán)、禁止訪問 Java 類庫中的危險類等,以減輕潛在的安全風(fēng)險。
  • 高性能: Painless 是為高性能而設(shè)計的,特別是在 Elasticsearch 中。它經(jīng)過了優(yōu)化,可以在大規(guī)模數(shù)據(jù)集上快速執(zhí)行。
  • 易學(xué)易用: Painless 實現(xiàn)了任何具有基本編碼經(jīng)驗的人都自然熟悉的語法。Painless 使用 Java 語法的子集,并進(jìn)行了一些額外的改進(jìn),以增強(qiáng)可讀性并刪除樣板文件。
  • 無需編譯: Painless 腳本不需要預(yù)先編譯。它可以在運行時解釋,所以我們可以動態(tài)調(diào)整腳本而無需重新編譯整個應(yīng)用程序。
  • 支持參數(shù)化: Painless 允許在腳本中使用參數(shù),這可以使腳本更通用,適用于多種情況。參數(shù)化腳本可以接受外部傳遞的值,從而在不修改腳本的情況下改變其行為。
  • 支持多種數(shù)據(jù)類型: Painless 支持多種數(shù)據(jù)類型,包括數(shù)字、字符串、日期、布爾值等。
  • 集成性: Painless 被緊密集成到 Java 中,可以用于查詢、聚合、腳本字段、腳本排序等各種用例。

3.1、編寫我們的第一個腳本

使用的Elasticsearch 版本為 8.1,歷史文章除非特別說明,最近更文的 ES版本都為 Elasticsearch 的 8.1 版本

腳本的組成有三個參數(shù),只要是在 Elasticsearch API 支持腳本的地方,都可以使用如下三個參數(shù)來使用腳本。

"script": {
    "lang":   "...",
    "source" | "id": "...",
    "params": { ... }
  }
  • lang:執(zhí)行腳本語言類型,默認(rèn)painless
  • source,id:腳本的源碼本身,或者提前存儲的腳本ID
  • params:作為變量傳遞給腳本的參數(shù)

下面我們將通過實際的例子來進(jìn)行說明

3.2、在檢索中使用腳本

首先我們先往索引中插入一篇文檔

PUT zfc-doc-000007/_doc/1
{
  "sum": 5,
  "message":"test painless"
}

使用腳本實現(xiàn) sum的值 乘2,此處使用變量 multiplier,在腳本的參數(shù)中指定參數(shù)值為2,其中doc['sum'].value * params['multiplier']的意思就是獲取文檔中sum的值并乘以腳本中 multiplier 的值

GET zfc-doc-000007/_search
{
  "script_fields": {
    "my_doubled_field": {
      "script": { 
        "source": "doc['sum'].value * params['multiplier']", 
        "params": {
          "multiplier": 2
        }
      }
    }
  }
}

在獲取腳本的參數(shù)中的變量值除了使用params['參數(shù)名']這種方式之外,還可以使用params.get('multiplier')方法獲取

GET zfc-doc-000007/_search
{
  "script_fields": {
    "my_doubled_field": {
      "script": {
        "lang":   "painless",
        "source": "doc['sum'].value * params.get('multiplier');",
        "params": {
          "multiplier": 2
        }
      }
    }
  }
}

上面我們是在檢索請求中使用的腳本字段來使用的腳本,下面我們先內(nèi)置一個腳本,通過使用腳本ID來使用內(nèi)置的腳本

3.3、使用內(nèi)置的腳本

創(chuàng)建一個腳本calculate-score,它可以使用Math.log(_score * 2) + params['my_modifier']修改分?jǐn)?shù)值

POST _scripts/calculate-score
{
  "script": {
    "lang": "painless",
    "source": "Math.log(_score * 2) + params['my_modifier']"
  }
}

創(chuàng)建完成的腳本我們可以使用_scriptAPI查看腳本的內(nèi)容

GET _scripts/calculate-score

在檢索中只需要如下指定腳本的ID即可進(jìn)行檢索時使用

GET zfc-doc-000007/_search
{
  "query": {
    "script_score": {
      "query": {
        "match": {
            "message": "painless"
        }
      },
      "script": {
        "id": "calculate-score", 
        "params": {
          "my_modifier": 2
        }
      }
    }
  }
}

如果想刪除腳本只需要調(diào)用DELETE 即可

DELETE _scripts/calculate-score

下面我們再來演示一下如何使用腳本更新文檔中的內(nèi)容

3.4、使用腳本操作文檔

先添加一個文檔來進(jìn)行測試

PUT zfc-doc-000007/_doc/1
{
  "counter" : 1,
  "tags" : ["red"]
}

使用腳本對文檔中的 counter 的值與腳本中的 count 值進(jìn)行相加

POST zfc-doc-000007/_update/1
{
  "script" : {
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params" : {
      "count" : 4
    }
  }
}

我們還可以對文檔中的數(shù)組類型的tags字段進(jìn)行增加子對象,比如增加一個blue

POST zfc-doc-000007/_update/1
{
  "script": {
    "source": "ctx._source.tags.add(params['tag'])",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

使用腳本對文檔中的 tags 的值進(jìn)行刪除,條件就是當(dāng) tag 的值與腳本中的值相等時刪除。如下為當(dāng) tags 的值為blue時,刪除blue

POST zfc-doc-000007/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params['tag'])) { ctx._source.tags.remove(ctx._source.tags.indexOf(params['tag'])) }",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

上面只是對已有字段的增加刪除修改,下面還可以使用腳本進(jìn)行新字段的增加,比如增加一個字段new_field,值是value_of_new_field

POST zfc-doc-000007/_update/1
{
  "script" : "ctx._source.new_field = 'value_of_new_field'"
}

上面是字段的增加,下面就是字段的移除

POST zfc-doc-000007/_update/1
{
  "script" : "ctx._source.remove('new_field')"
}

除了對字段的刪除,數(shù)組對象內(nèi)部值的刪除,還可以對文檔進(jìn)行刪除。如下,當(dāng) tags 里面包含 blue 時,刪除當(dāng)前文檔

POST zfc-doc-000007/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params['tag'])) { ctx.op = 'delete' } else { ctx.op = 'none' }",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

3.5、使用腳本解析日志信息

所謂的解析字符串,只是一組固定格式的字符串,提前使用變量的形式編譯,在插入文檔時,通過腳本進(jìn)行解析保存,方便后面的檢索等請求

假如我們有如下數(shù)據(jù)

"message" : "247.37.0.0 - - [30/Apr/2020:14:31:22 -0500] \"GET /images/hm_nbg.jpg HTTP/1.0\" 304 0"

那么我們可以使用如下變量的形式解析該字符串

%{clientip} %{ident} %{auth} [%{@timestamp}] \"%{verb} %{request} HTTP/%{httpversion}\" %{status} %{size}

下面我們使用例子來說明腳本解析字符串之后是何種形式的存在

創(chuàng)建一個索引保存解析的數(shù)據(jù)

PUT zfc-doc-000008
{
  "mappings": {
    "properties": {
      "message": {
        "type": "wildcard"
      }
    }
  }
}

內(nèi)置一個腳本,實現(xiàn)解析字符串信息,并提取需要的信息,如下為提取當(dāng)前日志中的 http 響應(yīng)信息response,對于如下腳本的測試API使用詳情可以參考官網(wǎng)

https://www.elastic.co/guide/en/elasticsearch/painless/8.1/pa...

POST /_scripts/painless/_execute
{
  "script": {
    "source": """
      String response=dissect('%{clientip} %{ident} %{auth} [%{@timestamp}] "%{verb} %{request} HTTP/%{httpversion}" %{response} %{size}').extract(doc["message"].value)?.response;
        if (response != null) emit(Integer.parseInt(response)); 
    """
  },
  "context": "long_field", 
  "context_setup": {
    "index": "zfc-doc-000008",
    "document": {          
      "message": """247.37.0.0 - - [30/Apr/2020:14:31:22 -0500] "GET /images/hm_nbg.jpg HTTP/1.0" 304 0"""
    }
  }
}

如果我們還想操作當(dāng)前解析的數(shù)據(jù)我們可以使用運行時字段,因為運行時字段不需要進(jìn)行索引會更加的靈活,可以很方便的修改腳本及運行方式。

那么我們現(xiàn)在刪除一下剛剛創(chuàng)建的索引,重新添加一下,創(chuàng)建語句如下

DELETE zfc-doc-000008
PUT /zfc-doc-000008
{
  "mappings": {
    "properties": {
      "@timestamp": {
        "format": "strict_date_optional_time||epoch_second",
        "type": "date"
      },
      "message": {
        "type": "wildcard"
      }
    }
  }
}

添加一個運行時字段來保存解析的結(jié)果

PUT zfc-doc-000008/_mappings
{
  "runtime": {
    "http.response": {
      "type": "long",
      "script": """
        String response=dissect('%{clientip} %{ident} %{auth} [%{@timestamp}] "%{verb} %{request} HTTP/%{httpversion}" %{response} %{size}').extract(doc["message"].value)?.response;
        if (response != null) emit(Integer.parseInt(response));
      """
    }
  }
}

添加幾條測試數(shù)據(jù)用于測試

POST /zfc-doc-000008/_bulk?refresh=true
{"index":{}}
{"timestamp":"2020-04-30T14:30:17-05:00","message":"40.135.0.0 - - [30/Apr/2020:14:30:17 -0500] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
{"index":{}}
{"timestamp":"2020-04-30T14:30:53-05:00","message":"232.0.0.0 - - [30/Apr/2020:14:30:53 -0500] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
{"index":{}}
{"timestamp":"2020-04-30T14:31:12-05:00","message":"26.1.0.0 - - [30/Apr/2020:14:31:12 -0500] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
{"index":{}}
{"timestamp":"2020-04-30T14:31:19-05:00","message":"247.37.0.0 - - [30/Apr/2020:14:31:19 -0500] \"GET /french/splash_inet.html HTTP/1.0\" 200 3781"}
{"index":{}}
{"timestamp":"2020-04-30T14:31:22-05:00","message":"247.37.0.0 - - [30/Apr/2020:14:31:22 -0500] \"GET /images/hm_nbg.jpg HTTP/1.0\" 304 0"}
{"index":{}}
{"timestamp":"2020-04-30T14:31:27-05:00","message":"252.0.0.0 - - [30/Apr/2020:14:31:27 -0500] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
{"index":{}}
{"timestamp":"2020-04-30T14:31:28-05:00","message":"not a valid apache log"}

下面我們進(jìn)行運行時字段檢索響應(yīng)為304的數(shù)據(jù)

GET zfc-doc-000008/_search
{
  "query": {
    "match": {
      "http.response": "304"
    }
  },
  "fields" : ["http.response"]
}

剛才是屬于提前內(nèi)置好運行時字段,我們也可以直接在檢索時指定運行時字段來使用,但下面所示的僅在運行時有效。如下所示

GET zfc-doc-000008/_search
{
  "runtime_mappings": {
    "http.response": {
      "type": "long",
      "script": """
        String response=dissect('%{clientip} %{ident} %{auth} [%{@timestamp}] "%{verb} %{request} HTTP/%{httpversion}" %{response} %{size}').extract(doc["message"].value)?.response;
        if (response != null) emit(Integer.parseInt(response));
      """
    }
  },
  "query": {
    "match": {
      "http.response": "304"
    }
  },
  "fields" : ["http.response"]
}

我們也可以根據(jù)特定的值進(jìn)行拆分,獲取所需要的信息

3.6、使用腳本解析 GC 信息

例如如下 Elasticsearch 的 GC 信息

[2021-04-27T16:16:34.699+0000][82460][gc,heap,exit]   class space    used 266K, capacity 384K, committed 384K, reserved 1048576K

下面我們根據(jù) GC 信息編寫一個解析模式

[%{@timestamp}][%[code]][%{desc}]  %{ident} used %{usize}, capacity %{csize}, committed %{comsize}, reserved %{rsize}

然后在檢索時就可以使用如下語句來提交信息到運行時字段,首先添加測試數(shù)據(jù),注意索引名稱已經(jīng)更換,解析模式不匹配會報錯

POST /zfc-doc-000010/_bulk?refresh
{"index":{}}
{"gc": "[2021-04-27T16:16:34.699+0000][82460][gc,heap,exit]   class space    used 266K, capacity 384K, committed 384K, reserved 1048576K"}
{"index":{}}
{"gc": "[2021-03-24T20:27:24.184+0000][90239][gc,heap,exit]   class space    used 15255K, capacity 16726K, committed 16844K, reserved 1048576K"}
{"index":{}}
{"gc": "[2021-03-24T20:27:24.184+0000][90239][gc,heap,exit]  Metaspace       used 115409K, capacity 119541K, committed 120248K, reserved 1153024K"}
{"index":{}}
{"gc": "[2021-04-19T15:03:21.735+0000][84408][gc,heap,exit]   class space    used 14503K, capacity 15894K, committed 15948K, reserved 1048576K"}
{"index":{}}
{"gc": "[2021-04-19T15:03:21.735+0000][84408][gc,heap,exit]  Metaspace       used 107719K, capacity 111775K, committed 112724K, reserved 1146880K"}
{"index":{}}
{"gc": "[2021-04-27T16:16:34.699+0000][82460][gc,heap,exit]  class space  used 266K, capacity 367K, committed 384K, reserved 1048576K"}

使用檢索語句展示解析數(shù)據(jù)到運行時字段中

GET zfc-doc-000010/_search
{
  "runtime_mappings": {
    "gc_size": {
      "type": "keyword",
      "script": """
        Map gc=dissect('[%{@timestamp}][%[code]][%{desc}]  %{ident} used %{usize}, capacity %{csize}, committed %{comsize}, reserved %{rsize}').extract(doc["gc.keyword"].value);
        if (gc != null) emit("used" + ' ' + gc.usize + ', ' + "capacity" + ' ' + gc.csize + ', ' + "committed" + ' ' + gc.comsize);
      """
    }
  },
  "size": 1,
  "aggs": {
    "sizes": {
      "terms": {
        "field": "gc_size",
        "size": 10
      }
    }
  },
  "fields" : ["gc_size"]
}

通過上面的查詢測試可以知道,Elasticsearch 中的 script 默認(rèn)的時 painless 語言,功能已經(jīng)非常強(qiáng)大可以滿足我們的日常需求,如果還想更高級的腳本,可以使用 Java 語言來編寫自己的腳本。關(guān)于 Expressions 的表達(dá)式的使用就參與官網(wǎng)吧,本文的所有例子均來自官網(wǎng),并自測完成。如有錯誤歡迎指出,共同進(jìn)步。

以上就是Elasticsearch8.1中的Script使用實例深入解讀的詳細(xì)內(nèi)容,更多關(guān)于Elasticsearch8.1 Script的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java字符串查找的三種方式

    Java字符串查找的三種方式

    本篇文章給大家整理了關(guān)于Java字符串查找的三種方式,并把其中需要留意的地方做了標(biāo)注,一起參考學(xué)習(xí)下。
    2018-03-03
  • Java中的Lock使用實例詳解

    Java中的Lock使用實例詳解

    在多線程編程中,鎖是保證數(shù)據(jù)一致性的關(guān)鍵工具,Java從JDK1.5開始提供了java.util.concurrent.locks包,其中的Lock接口及其實現(xiàn)類比傳統(tǒng)的synchronized更加強(qiáng)大和靈活,這篇文章主要介紹了Java中Lock使用的相關(guān)資料,需要的朋友可以參考下
    2026-03-03
  • Java Scanner用法案例詳解

    Java Scanner用法案例詳解

    這篇文章主要介紹了Java Scanner用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 解決java文件流處理異常 mark/reset not supported問題

    解決java文件流處理異常 mark/reset not supported問題

    這篇文章主要介紹了解決java文件流處理異常 mark/reset not supported問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java獲取視頻時長及截取幀截圖詳解

    Java獲取視頻時長及截取幀截圖詳解

    這篇文章主要介紹了Java獲取視頻時長及截取幀截圖詳解,以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。,需要的朋友可以參考下
    2019-06-06
  • 細(xì)數(shù)java中Long與Integer比較容易犯的錯誤總結(jié)

    細(xì)數(shù)java中Long與Integer比較容易犯的錯誤總結(jié)

    下面小編就為大家?guī)硪黄?xì)數(shù)java中Long與Integer比較容易犯的錯誤總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Spring?Bean后處理器詳細(xì)介紹

    Spring?Bean后處理器詳細(xì)介紹

    Bean后置處理器允許在調(diào)用初始化方法前后對Bean進(jìn)行額外的處理??梢栽?Spring容器通過插入一個或多個BeanPostProcessor的實現(xiàn)來完成實例化,配置和初始化一個?bean?之后實現(xiàn)一些自定義邏輯回調(diào)方法
    2023-01-01
  • 深度解析Spring Bean生命周期以及LomBok插件

    深度解析Spring Bean生命周期以及LomBok插件

    本文詳細(xì)介紹了Spring框架中Bean的生命周期,包括核心差異、完整階段拆解、回調(diào)方法實現(xiàn)方式及優(yōu)先級,Bean后置處理器的關(guān)鍵知識點,并通過實戰(zhàn)測試驗證了整個生命周期流程,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Java中@Accessors注解的具體使用

    Java中@Accessors注解的具體使用

    @Accessors是Lombok提供的注解之一,用于自動生成getter和setter方法,本文主要介紹了@Accessors注解的常用屬性,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • SpringSecurity實現(xiàn)動態(tài)加載權(quán)限信息的方法

    SpringSecurity實現(xiàn)動態(tài)加載權(quán)限信息的方法

    這篇文章主要介紹了SpringSecurity實現(xiàn)動態(tài)加載權(quán)限信息,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定需要的朋友可以參考下
    2022-01-01

最新評論

石阡县| 巩留县| 华安县| 潜山县| 浦北县| 平舆县| 佛教| 镇江市| 龙岩市| 龙州县| 金平| 阿拉善左旗| 美姑县| 博乐市| 寿阳县| 望奎县| 乐清市| 武乡县| 翁牛特旗| 仙桃市| 民权县| 鄢陵县| 潮州市| 吉首市| 瑞昌市| 鞍山市| 钦州市| 邢台县| 绥德县| 盐边县| 泰安市| 吉林市| 高要市| 南郑县| 普宁市| 塔城市| 突泉县| 商河县| 克山县| 凤冈县| 龙海市|