1.ES---腳本化字段

腳本化 field 示例

本小節展示了 Kibana 中一些常見場景下的 Lucene expressions 和 Painless 腳本化 field 示例。如上所述,這些示例以來自 Kibana 入門教程的數據集爲基礎,並且假定你使用的是 Elasticsearch 和 Kibana 5.1.1,因爲在之前的版本中,某些類型的腳本化 field 中存在一些與過濾和排序相關的已知問題。

由於 Elasticsearch 5.0 默認啓用 Lucene expressions 和 Painless,因此腳本化 fields 在大部分情況下應該都能夠開箱即用。唯一例外的是那些需要對 fields 進行基於正則表達式的解析的腳本,這些腳本需要你在 elasticsearch.yml中設置下面的設置,爲 Painless 打開正則表達式匹配:

script.painless.regex.enabled: true

對單個 field 執行計算
示例:由字節計算出千字節
語言:expressions
返回類型:數字

 doc['bytes'].value / 1024

注意:切記 Kibana 腳本化 fields 一次只能處理一個單獨的文檔,因此無法在腳本化 fields 中進行時間序列運算。

返回數字的日期運算
示例:將日期解析成小時時間
語言:expressions
返回類型:數字
Lucene expressions 提供了大量開箱即用的 日期處理函數。但是,由於 Lucene expressions 只能返回數字值,因此我們必須使用 Painless 來返回基於字符串的星期值(如下所示)。

 doc['@timestamp'].date.hourOfDay

注意:上面的腳本將返回 1-24

doc['@timestamp'].date.dayOfWeek

注意:上面的腳本將返回 1-7

合併兩個字符串值
示例:合併源和目標或名字和姓氏
語言:painless
返回類型:字符串

 doc['geo.dest.keyword'].value + ':' + doc['geo.src.keyword'].value

注意:由於腳本化 field 需要操作doc_values中的 field,因此我們上面使用的是 .keyword 版本的字符串。

引入邏輯運算
示例:爲所有超過 10000 字節的文檔返回標籤“big download”
語言:painless
返回類型:字符串

 if (doc['bytes'].value > 10000) { 
    return "big download";
}
return "";

注意:引入邏輯運算時,確保每個執行路徑都具有良好定義的返回語句和良好定義的返回值(而非 null)。例如,在 Kibana 過濾器中使用上述腳本化 field 時,如果最後沒有返回語句或者語句返回 null,都會出現編譯錯誤。另外還請注意,Kibana 腳本化 field 中不支持將邏輯運算分解成函數。

返回子串
示例:返回 URL 中最後一個斜線後面的部分
語言:painless
返回類型:字符串

 def path = doc['url.keyword'].value;
if (path != null) {
    int lastSlashIndex = path.lastIndexOf('/');
    if (lastSlashIndex > 0) {
    return path.substring(lastSlashIndex+1);
    }
}
return "";

注意:儘量避免使用正則表達式提取子串,因爲 indexOf() 操作佔用的資源更少,更不易出錯。

使用正則表達式匹配字符串,並對匹配進行操作
示例:如果在 field“referer”中找到子串“error”,則返回字符串“error”,否則返回字符串“no error”。
語言:painless
返回類型:字符串

if (doc['referer.keyword'].value =~ /error/) { 
return "error"
} else {
return "no error"
}

注意:簡化的正則表達式語法對基於正則表達式匹配的條件句有用。

匹配字符串並返回該匹配
示例:返回域,即 field “host”中最後一個點後面的字符串。
語言:painless
返回類型:字符串

def m = /^.*\.([a-z]+)$/.matcher(doc['host.keyword'].value);
if ( m.matches() ) {
   return m.group(1)
} else {
   return "no match"
}

注意:通過正則表達式 matcher() 函數定義對象,可以提取與正則表達式相匹配的字符組並將它們返回。

匹配數字並返回該匹配
示例:返回 IP 地址的第一個八位組(存儲爲字符串)並將它視爲一個數字。
語言:painless
返回類型:數字

 def m = /^([0-9]+)\..*$/.matcher(doc['clientip.keyword'].value);
if ( m.matches() ) {
   return Integer.parseInt(m.group(1))
} else {
   return 0
}

注意:在腳本中返回正確的數據類型是很重要的。正則表達式匹配返回的是字符串,即便匹配的是數字依然返回字符串,因此返回時應該顯式地將它轉換成整數。

返回字符串的日期運算
示例:將日期解析成星期值再解析成字符串
語言:painless
返回類型:字符串

LocalDateTime.ofInstant(Instant.ofEpochMilli(doc['@timestamp'].value), ZoneId.of('Z')).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault())

注意:由於 Painless 支持 Java 所有的原生類型,因此通過它可以獲取與這些類型相關的原生函數,例如 LocalDateTime(),這在執行更加高級的日期運算時有用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章