1. 程式人生 > 其它 >ES elasticsearch ingest如何使用及painless指令碼

ES elasticsearch ingest如何使用及painless指令碼

Painless 指令碼為我們的搜尋帶來了很多的方便和靈活性,但是在很多的實踐中,我們需要認真地思考這個指令碼是不是最有效的。特別是,當我們在 query 使用指令碼時,我們需要特別注意。這是因為在搜尋時,需要針對每個文件進行計算,當我們的文件的數量很大時,那麼這個計算量將會是非常大,從而影響搜尋的效率。

比如,我們建立如下的一個文件:

PUT twitter/_doc/1
{
"user" : "雙榆樹-張三",
"message" : "今兒天氣不錯啊,出去轉轉去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中國",
"address" : "中國北京市海淀區",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
假如我們想搜尋 message 欄位的長度大於 10 的所有文件,我們可以通過如下的方法來獲得。

GET twitter/_search
{
"query": {
"script": {
"script": {
"lang": "painless",
"source": "doc['message.keyword'].value.length() > params.length",
"params": {
"length": 10
}
}
}
}
}
在上面我們使用指令碼來計算 message 欄位的長度,並返回所有 message 欄位長度超過 10 的文件。

上面的搜尋咋一看,沒有任何毛病,但是假設我們的文件數目有很多(比如幾萬個資料),那麼上面的這個在搜尋時的計算量將是非常大的,從而會影響搜尋的效率。那麼我們有什麼好的方法來解決這個問題呢?

我們可以把這個計算放到 index 時候,也就是在建立索引的時候。比如我們可以這麼做:

DELETE twitter

PUT _ingest/pipeline/calculate_length
{
"description": "Calculate the length of message",
"processors": [
{
"script": {
"source": """
ctx.length = ctx.message.length()
"""
}
}
]
}
在上面,我們先刪除之前建立的 twitter 索引,然後建立一個計算 message 欄位長度的一個指令碼 processor。在匯入一個文件時,我們使用如下的方法:

PUT twitter/_doc/1?pipeline=calculate_length
{
"user": "雙榆樹-張三",
"message": "今兒天氣不錯啊,出去轉轉去",
"uid": 2,
"age": 20,
"city": "北京",
"province": "北京",
"country": "中國",
"address": "中國北京市海淀區",
"location": {
"lat": "39.970718",
"lon": "116.325747"
}
}
由於我們使用了 calculate_length 這個 pipeline,那麼它將會為我們建立一個新的叫做 length 的欄位。我們通過如下的方法來進行查詢:

GET twitter/_search
上面顯示的結果為:

{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"country" : "中國",
"address" : "中國北京市海淀區",
"city" : "北京",
"length" : 13,
"message" : "今兒天氣不錯啊,出去轉轉去",
"uid" : 2,
"province" : "北京",
"location" : {
"lon" : "116.325747",
"lat" : "39.970718"
},
"user" : "雙榆樹-張三",
"age" : 20
}
}
]
}
}
我們可以看到一個新增加的 length 欄位。上面顯示的值為 13 。那麼有了這個欄位,我們就可以通過如下的方法來進行查詢了:

GET twitter/_search
{
"query": {
"range": {
"length": {
"gte": 10
}
}
}
}
在上面,我們使用了新增加的 length 欄位來查詢我們的文件。這樣可以大大地提供搜尋的效率。

原文連結:Elastic 中國社群官方部落格

螃蟹在剝我的殼,筆記本在寫我,漫天的我落在楓葉上雪花上,而你在想我。 --章懷柔