ElasticSearch笔记-管道处理器
管道处理器
管道中包含多个处理器,管道中具体的处理逻辑取决于处理器。可以在创建管道时指定处理器:
PUT _ingest/pipeline/test_pipeline
{
"processors": [
{
"set": {
"field": "des",
"value": "管道默认数据"
}
},
{
"set": {
"field": "des2",
"value": "管道默认数据2"
}
}
]
}
目前有32种管道处理器
- Set Processor
设置参数处理器,作用是将指定内容的值设置到指定的字段中。 - HTML Strip Processor
HTML标签处理器,作用是将字段中的HTML标签移除 - Lowercase Processor
小写处理器,作用是将字段中的字符串转换为其等效的小写形式。 - Uppercase Processor
大写处理器,作用是将字段中的字符串转换为其等效的大写形式。 - Trim Processor
空符号去除处理器,作用是将字段内容开头和结尾处的空白字符删除。 - Bytes Processor
字节处理器,将可读的字节值(如1kb)转换为其实际的字节数值值(如1024)。可读的字节单位包含“b”、“kb”、“mb”、“gb”、“tb”、“pb”。此单位不区分大小写。如果字段中单位不符合支持的内容,或者结果大于2^63,则报错。 - Convert Processor
类型转换处理器,将字段转换为另外一种数据类型,如果字段的值是一个数组,将会将其内部成员进行转换。 - Date Processor
日期转换处理器,将字段内容按照日期格式进行解析,默认情况下,日期处理器将解析后的日期添加为一个名为@timestamp的新字段。 - JSON Processor
JSON对象转换处理器,将文档字段中JSON字符串解析成JSON对象的处理器 - Drop Processor
将符合条件的文档从请求中剔除出去,防止文档在某些情况下创建索引。 - Foreach Processor 循环处理
- Remove Processor
移除处理器,删除文档中的字段,如果字段不存在则抛出异常。 - Rename Processor
重命名处理器,重命名现有字段。如果字段不存在或已经使用了新名称,则会引发异常。 - Script Processor
脚本处理器,此处理器允许在接收管道中执行内联和存储的脚本 - Fail Processor
故障处理,此处理器用于把符合条件的管道失败并返回特定消息到请求者。 - Pipeline Processor 管道委托
- URL Decode Processor URL解码处理器
- Dissect Processor 数据解析处理器
- Dot Expander Processor 点扩展解析处理器
- GeoIP Processor IP解析处理器
- Grok Processor Grok解析处理器
- Gsub Processor Gsub解析处理器
- KV Processor 键值对解析处理器
- Append Processor 数据追加处理器
- Join Processor 拼接处理器
- Split Processor 分割处理器
- Sort Processor 排序处理器
- Date Index Name Processor 日期类索引定位处理器
- Set Security User Processor 设置安全用户处理器
- User Agent processor 用户代理处理器
处理器公共属性
if
每个处理器都允许一个可选的if条件来决定应该执行还是跳过该处理器。if的值为true或false。
案例:现在创建一个管道,当遇见description为‘description1’的数据时就不进行操作。
PUT _ingest/pipeline/not_save
{
"processors": [
{
"drop": {
"if": "ctx.description == 'description1'"
}
}
]
}
然后尝试保存下面数据,并且使用not_save管道
PUT index10/_doc/2?pipeline=not_save
{
"id": 2,
"description": "description1"
}
发现文档没有添加成功
on_failure
处理器发生异常后执行的逻辑,正常使用中,管道定义的处理列表是按照顺序执行的,当处理过程中存在异常时处理便会停止。在无法保证异常是否发生的环境中,让异常直接终止处理的方法显然不合理。当我们预期到某些异常的存在时,我们应该有另外一种方式去处理而不是停止程序。
on_failure参数定义了在发生故障的处理器之后立即执行的处理器列表。on_failure参数可以设置在管道中也可以设置在管道内的处理器中。
案例:
将foo字段修改为bar字段,但是当foo的字段不存在的时候会发生异常,这个时候会执行on_failure内部的逻辑
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "_description",
"processors": [
{
"rename": {
"field": "foo",
"target_field": "bar",
"on_failure": [
{
"set": {
"field": "error",
"value": "field \"foo\" does not exist, cannot rename to \"bar\""
}
}
]
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"boo": "boo1"
}
},
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "foo2",
"boo": "boo2"
}
}
]
}
其执行后的结果,可以看到第一条数据已经存在error的信息
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo1",
"error" : """field "foo" does not exist, cannot rename to "bar""""
},
"_ingest" : {
"timestamp" : "2019-11-27T02:56:07.757485Z"
}
}
},
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"bar" : "foo2",
"boo" : "boo2"
},
"_ingest" : {
"timestamp" : "2019-11-27T02:56:07.757497Z"
}
}
}
]
}
获取异常信息:
类似try-catch中的(Exception e)的逻辑,我们可以获取异常中的信息,而ES也提供了获取异常信息的方式。其异常信息放在_ingest,此参数可以获取的内容为on_failure_message、on_failure_processor_type和on_failure_processor_tag的元数据字段。需要注意的上面的内容只能在on_failure代码块中访问
"on_failure" : [
{
"set" : {
"field" : "error",
"value" : "{{ _ingest.on_failure_message }}"
}
}
]
指向新索引:
这是官方提供的一个异常处理的应用方式。将错误数据指向到一个新的索引中是个非常好的处理方式,当我们批量执行操作遇见错误的数据被保存到一个错误索引表中,我们就可以专门针对这张索引进行分析和处理。
"on_failure" : [
{
"set" : {
"field" : "_index",
"value" : "failed-{{ _index }}"
}
}
]
ignore_failure
是否忽略异常处理
有的时候我们可能并不关心异常的内容和原因,仅仅是想完成一些操作,这个时候可以使用"ignore_failure" : true配置来让系统忽略掉所有异常。
{
"description" : "my first pipeline with handled exceptions",
"processors" : [
{
"rename" : {
"field" : "foo",
"target_field" : "bar",
"ignore_failure" : true
}
}
]
}
pipeline处理器
委托给其他管道
1、创建管道last_pipeline
PUT _ingest/pipeline/last_pipeline
{
"processors": [
{
"set": {
"field": "foo",
"value": "last_foo_value"
}
}
]
}
2、如果foo==foo1,委托给last_pipeline管道处理
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "_description",
"processors": [
{
"pipeline": {
"if": "ctx.foo == 'foo1'",
"name": "last_pipeline"
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "foo1",
"boo": "boo1"
}
},
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "foo2",
"boo": "boo2"
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo1",
"foo" : "last_foo_value"
},
"_ingest" : {
"timestamp" : "2022-02-15T10:19:07.02583Z"
}
}
},
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo2",
"foo" : "foo2"
},
"_ingest" : {
"timestamp" : "2022-02-15T10:19:07.025839Z"
}
}
}
]
}
html_strip、lowercase、uppercase、trim处理器
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"lowercase": {
"field": "foo"
}
},
{
"html_strip": {
"field": "foo"
}
},
{
"trim": {
"field": "boo"
}
},
{
"uppercase": {
"field": "boo"
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": " <span>Foo1</span> ",
"boo": " boo1 "
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "BOO1",
"foo" : " foo1 "
},
"_ingest" : {
"timestamp" : "2022-02-16T06:16:42.796125Z"
}
}
}
]
}
gsub处理器
通过应用正则表达式和替换来转换字符串字段。如果字段不是字符串,处理器将抛出异常。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"gsub": {
"field": "foo",
"pattern":"\\.",
"replacement": "-"
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": " a.b ",
"boo": "boo1"
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo1",
"foo" : " a-b "
},
"_ingest" : {
"timestamp" : "2022-02-16T06:34:02.129555Z"
}
}
}
]
}
bytes处理器
将可读的字节值(如1kb)转换为其实际的字节数值值(如1024)。可读的字节单位包含“b”、“kb”、“mb”、“gb”、“tb”、“pb”。
此单位不区分大小写。如果字段中单位不符合支持的内容,或者结果大于2^63,则会出现错误。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"bytes": {
"field": "foo",
"target_field": "foo_value",
"on_failure": [
{
"set":{
"field":"error",
"value":"{{_ingest.on_failure_message}}"
}
}
]
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "1mb",
"boo": "boo1"
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo1",
"foo_value" : 1048576,
"foo" : "1mb"
},
"_ingest" : {
"timestamp" : "2022-02-16T06:59:26.631797Z"
}
}
}
]
}
urldecode处理器
将被UrlEncode编码的内容进行解码。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"urldecode": {
"field": "foo"
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "https%3A%2F%2Fwww.cnblogs.com%2Ffanfan-90%2F",
"boo": "boo1"
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"boo" : "boo1",
"foo" : "https://www.cnblogs.com/fanfan-90/"
},
"_ingest" : {
"timestamp" : "2022-02-16T07:05:56.441294Z"
}
}
}
]
}
date处理器
将字段内容按照日期格式进行解析,默认情况下,日期处理器将解析后的日期添加为一个名为@timestamp的新字段。也可以通过target_field配置指定不同的字段,其支持多种日期格式,会按照顺序尝试解析date字段。其顺序取决于处理器定义的顺序。
参数:
field 必填 - 需要操作的字段
formats 必填 - 预期日期格式,数组类型。可以是java时间模式,也可以是下列格式之一:ISO8601、UNIX、UNIX_MS或TAI64N
timezone 非必填 UTC 解析日期时使用的时区。支持模板片段
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"date": {
"field": "foo",
"target_field":"date",
"formats": ["yyyy/MM/dd HH:mm:ss"]
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"foo": "2022/02/16 00:00:00",
"boo": "boo1"
}
}
]
}
结果:
{
"docs" : [
{
"doc" : {
"_index" : "index",
"_type" : "_doc",
"_id" : "id",
"_source" : {
"date" : "2022-02-16T00:00:00.000Z",
"boo" : "boo1",
"foo" : "2022/02/16 00:00:00"
},
"_ingest" : {
"timestamp" : "2022-02-16T07:58:14.647517Z"
}
}
}
]
}
convert处理器
类型转换处理器,将输入的文档字段转换为另外一种数据类型,如果字段的值是一个数组,将会将其内部成员进行转换。
类型转换只支持的数据类型:integer, long, float, double, string, boolean, auto。
如果指定字符串转换为布尔值的时候,如果其字符串值为true(忽略大小写),则将返回true,如果其字符串值为false(忽略大小写),则返回false。其他内容则会抛出异常。
指定转换为auto则尝试将字符串值字段转换为最近的非字符串类型。比如“true”的字段将被转换为布尔类型:true。如果提供的字段不能进行适当的转换,转换处理器仍然会成功地处理并保持字段值不变。在这种情况下,target_field仍然会使用未转换的字段值进行更新。在auto中float优先于double。值“242.15”将“自动”转换为类型为float的242.15。
参数:
field 必填 - 需要操作的字段
target_field 非必填 field 需要将处理之后的内容赋值的目标字段,默认情况下将就地更新
type 必填 - 需要转换的目标数据类型
PUT _ingest/pipeline/my-pipeline-id
{
"description": "converts the content of the id field to an integer",
"processors" : [
{
"convert" : {
"field" : "id",
"type": "integer"
}
}
]
}
使用_simulate模拟此处理器效果,尝试将foo内容转换为整数。提供了两个文档数据,第一个可以正确转换成整数,第二个则不可以。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "类型转换处理器",
"processors": [
{
"convert": {
"field": "foo",
"type": "integer",
"on_failure": [
{
"set": {
"field": "error",
"value": "{{ _ingest.on_failure_message }}"
}
}
]
}
}
]
},
"docs": [
{
"_index": "1",
"_id": "1",
"_source": {
"foo": "1000",
"boo": "1000"
}
},
{
"_index": "1",
"_id": "1",
"_source": {
"foo": "1000L"
}
}
]
}
此时的返回内容中第二条文档数据并没有被转换,且录入的一条错误记录。而第一条记录中foo已经被转换为1000的整数表示,而boo字段依旧是1000的字符串表示。
{
"docs" : [
{
"doc" : {
"_index" : "1",
"_type" : "_doc",
"_id" : "1",
"_source" : {
"boo" : "1000",
"foo" : 1000
},
"_ingest" : {
"timestamp" : "2019-12-03T01:54:43.864673Z"
}
}
},
{
"doc" : {
"_index" : "1",
"_type" : "_doc",
"_id" : "1",
"_source" : {
"error" : """For input string: \"1000L\"""",
"foo" : "1000L"
},
"_ingest" : {
"timestamp" : "2019-12-03T01:54:43.864681Z"
}
}
}
]
}
json处理器
将文档字段中JSON字符串解析成JSON对象的处理器
JSON字符串中的对象将被解析成JSON支持的类型(null、boolean、number、array、object、string)。
{
"json" : {
"field" : "string_source",
"target_field" : "json_target"
}
}
使用_simulate模拟此处理器效果,尝试将foo的JSON字符串解析为JSON对象。下面例子中将foo字段中的内容按照JSON对象进行解析
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "JSON对象处理器",
"processors": [
{
"json": {
"field": "foo",
"target_field": "foo_json"
}
}
]
},
"docs": [
{
"_index": "1",
"_id": "1",
"_source": {
"foo": "{\"user\":\"大风\"}"
}
}
]
}
上面的请求返回的内容,中JSON字符串中的user被解析到了foo_json字段下面。
{
"docs" : [
{
"doc" : {
"_index" : "1",
"_type" : "_doc",
"_id" : "1",
"_source" : {
"foo_json" : {
"user" : "大风"
},
"foo" : """{"user":"大风"}"""
},
"_ingest" : {
"timestamp" : "2019-12-06T13:00:47.457056Z"
}
}
}
]
}
此处理器提供了一个add_to_root参数,使用此参数的时候需要不能设置target_field。这个时候解析的内容会直接添加到文档的根节点下。
{
"docs" : [
{
"doc" : {
"_index" : "1",
"_type" : "_doc",
"_id" : "1",
"_source" : {
"user" : "大风",
"foo" : """{"user":"大风"}"""
},
"_ingest" : {
"timestamp" : "2019-12-06T13:06:27.29748Z"
}
}
}
]
}