- Tags 欄位中,逗號分割的文字應該是陣列,而不是一個字串
- 需求:後期需要對 Tags 進行 Aggregation 統計
- Elasticsearch 5.0 後,引入的一種新的節點型別。預設配置下,每個節點都是 Ingest Node
- 具有預處理資料的能力,可攔截 Index 或者 Bulck API 的請求
- 對資料進行轉換,並重新返回給 Index 和 Bluck API
- 無需 Logstash ,就可以進行資料的預處理,例如
- 為某個欄位設定預設值;重新命名某個欄位的欄位名;對欄位值進行 Split 操作
- 支援設定 Painless 指令碼,對資料進行更加複雜的加工
- Pipeline - 管道會對通過的資料(文件),按照順序進行加工
- Processor - Elasticsearch 對一些加工的行為進行了抽象包裝
- Elasticsearch 有很多內建的 Processors。也支援通過外掛的方式,實現自己的 Processsor
使用 Pipeline 切分字串
# 測試split tags
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "to split blog tags",
"processors": [
{
"split": {
"field": "tags",
"separator": ","
}
}
]
},
"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"
}
}
]
}
為文件增加欄位
#同時為文件,增加一個欄位。blog檢視量
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "to split blog tags",
"processors": [
{
"split": {
"field": "tags",
"separator": ","
}
},
{
"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"
}
}
]
}
Pipeline API
新增 Pipeline 並測試
# 為ES新增一個 Pipeline
PUT _ingest/pipeline/blog_pipeline
{
"description": "a blog pipeline",
"processors": [
{
"split": {
"field": "tags",
"separator": ","
}
},
{
"set": {
"field": "views",
"value": 0
}
}
]
}
#測試pipeline
POST _ingest/pipeline/blog_pipeline/_simulate
{
"docs": [
{
"_source": {
"title": "Introducing cloud computering",
"tags": "openstack,k8s",
"content": "You konw, for cloud"
}
}
]
}
Index & Update By Query
#不使用pipeline更新資料
PUT tech_blogs/_doc/1
{
"title":"Introducing big data......",
"tags":"hadoop,elasticsearch,spark",
"content":"You konw, for big data"
}
#使用pipeline更新資料
PUT tech_blogs/_doc/2?pipeline=blog_pipeline
{
"title": "Introducing cloud computering",
"tags": "openstack,k8s",
"content": "You konw, for cloud"
}
#檢視兩條資料,一條被處理,一條未被處理
POST tech_blogs/_search
{}
#update_by_query 會導致錯誤
POST tech_blogs/_update_by_query?pipeline=blog_pipeline
{
}
#增加update_by_query的條件
POST tech_blogs/_update_by_query?pipeline=blog_pipeline
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "views"
}
}
}
}
}
一些內建的 Processors
- https://www.elastic.co/guide/en/elasticsea...
- Split Processor (例如:將給定欄位分成一個陣列)
- Remove / Rename Processor (移除一個重新命名欄位)
- Append(為商品增加一個新的標籤)
- Convert (將商品價格,從字串轉換成 float 型別)
- Date / JSON (日期格式轉換,字串轉 JSON 物件)
- Date Index Name Processor (將通過該處理器的文件,分配到指定時間格式的索引中)
- Fail Processor (一旦出現異常,該 Pipeline 指定的錯誤資訊能返回給使用者)
- Foreach Process (陣列欄位,陣列的每個元素都會使用到一個相同的處理器)
- Grok Processor (日誌的日誌格式切割)
- Gsub / Join / Split (字串替換、陣列轉字串、字串轉陣列)
- Lowercase / Upcase(大小寫轉換)
Ingest Node v.s Logstash
Logstash |
Ingest Node |
---|
資料輸入與輸出 |
支援從不同的資料來源讀取,並寫入不同的資料來源 |
支援從ES REST API 獲取資料,並且寫入ES |
資料來源緩衝 |
實現了簡單的資料佇列,支援重寫 |
不支援緩衝 |
資料處理 |
支援大量的的外掛,也支援定製開發 |
內建的外掛,可以開發 Plugin 進行擴充套件(Plugin 更新需要重啟) |
配置和使用 |
增加了一定的架構複雜度 |
無需額外部署 |
https://www.elastic.co/cn/blog/should-i-us...
- 自 ES 5.x 後引入,專門為 ES 設定,擴充套件了 Java 的語法
- 6.0 開始,ES 只支援 Painless。Grooby ,JavaScript 和 Python 都不在支援
- Painless 支援所有的 Java 的資料型別及 Java API 子集
- Painless Script 具備以下特性
Painless 的用途
- 可以對文件欄位進行加工處理
- 更新或者刪除欄位,處理資料聚合操作
- Script Field: 對返回的欄位提前進行計算
- Function Score:對文件的算分進行處理
- 在Ingest Pipeline 中執行指令碼
- 在Reindex API,Update By Query 時,對資料進行處理
通過 Painless 指令碼訪問欄位
上線文 |
語法 |
---|
Ingestion |
ctx.field_name |
Update |
ctx._source.field_name |
Search & Aggregation |
doc{"field_name"] |
案例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"
}
}
]
}
案例2:文件更新計數
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計數
POST tech_blogs/_search
案例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": {}
}
}
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
}
}
}
指令碼快取
- 編譯的開銷相較大
- Elasticsearch 會將甲苯編譯後快取在 Cache 中
- Inline scripts 和 Stored Scripts 都會被快取
- 預設快取 100個指令碼
- 概念講解:Ingest Node,Pipeline 與 Processor
- Ingest Node 與 Logstash 的⽐較
- Pipeline 的 相關操作 / 內建 Processor 講解與演示
- Painless 指令碼與
- Ingestion (Pipeline)
- Update
- Search & Aggregation
本作品採用《CC 協議》,轉載必須註明作者和本文連結