Elasticsearch 摄取管道脚本处理器无法投射
Elasticsearch ingest pipeline script processor fails to cast
我正在尝试重新索引数据并根据源文档中的字段进行一些计算。
我已经使用摄取管道通过 geo_point 丰富了文档,并且还想计算一些其他值。
我遇到的问题是源数据抛出一个错误,指出无法转换。详情在这里:
原始(来自 ML csv 输入):
"_source": {
"Time": "18.06.2017 17:37:32",
"Weight (kg)": 286000,
"People": 2,
"Seats": "2"}
然而,用ML做的导入明确说明如下:
{
"convert": {
"field": "Seats",
"type": "long",
"ignore_missing": true
}
},{
"convert": {
"field": "People",
"type": "long",
"ignore_missing": true
}
}
传入的原始数据是一致的,所有值都是严格的数字,没有引号等(前 3 个是重量、座位和人数:
66990;189;172;0;0;0;0;0
稍后还要说明索引的 mapping/mapping 模板,该模板也显示了正确的类型:
"People": {
"type": "long"
},
"Seats": {
"type": "long"
},
现在,当我使用 Kibana 脚本字段时,我可以计算如下:
if (doc['Seats'].value == 0)
{ return 0 } else
{
long utilization = (doc["People"].value * 100)/doc["Seats"].value;
return utilization
}
一切正常,我得到了计算得出的利用率。
当我尝试像这样对摄取管道中的脚本执行相同操作时:
"caused_by" : {
"type" : "class_cast_exception",
"reason" : "cannot explicitly cast float [java.lang.String] to byte"
}
我使用的代码如下:
"script": {
"if": "!(ctx.Seats=0) && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = (float)ctx.People*100.0/(float)ctx.Seats"
}
我的问题是:
- 为什么 ML 摄取的行为不同(来自 csv 的原始数据完全相同,只有整数)
- 我可以在摄取管道中做什么来完成它
- kibana 索引模式是否与摄取管道一样高效,或者我应该在负载等方面坚持使用摄取管道
感谢您的帮助和提示。
千比助
在摄取管道中,ctx.Seats
仍然是一个字符串,因为它是源文档中的一个字符串。您要么需要在脚本中解析它,要么在脚本之前转换它。
没有转换的选项,只是解析脚本中的值:
"script": {
"if": "!(ctx.Seats=="0") && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = 100.0 * ctx.People / Float.parseFloat(ctx.Seats)"
}
在 运行 脚本之前进行转换的选项:
{
"convert" : {
"field" : "Seats",
"type": "float",
"ignore_missing": true
}
},
{
"script": {
"if": "!(ctx.Seats==0) && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = 100.0 * ctx.People / ctx.Seats"
}
}
我正在尝试重新索引数据并根据源文档中的字段进行一些计算。 我已经使用摄取管道通过 geo_point 丰富了文档,并且还想计算一些其他值。
我遇到的问题是源数据抛出一个错误,指出无法转换。详情在这里:
原始(来自 ML csv 输入):
"_source": {
"Time": "18.06.2017 17:37:32",
"Weight (kg)": 286000,
"People": 2,
"Seats": "2"}
然而,用ML做的导入明确说明如下:
{
"convert": {
"field": "Seats",
"type": "long",
"ignore_missing": true
}
},{
"convert": {
"field": "People",
"type": "long",
"ignore_missing": true
}
}
传入的原始数据是一致的,所有值都是严格的数字,没有引号等(前 3 个是重量、座位和人数:
66990;189;172;0;0;0;0;0
稍后还要说明索引的 mapping/mapping 模板,该模板也显示了正确的类型:
"People": {
"type": "long"
},
"Seats": {
"type": "long"
},
现在,当我使用 Kibana 脚本字段时,我可以计算如下:
if (doc['Seats'].value == 0)
{ return 0 } else
{
long utilization = (doc["People"].value * 100)/doc["Seats"].value;
return utilization
}
一切正常,我得到了计算得出的利用率。
当我尝试像这样对摄取管道中的脚本执行相同操作时:
"caused_by" : {
"type" : "class_cast_exception",
"reason" : "cannot explicitly cast float [java.lang.String] to byte"
}
我使用的代码如下:
"script": {
"if": "!(ctx.Seats=0) && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = (float)ctx.People*100.0/(float)ctx.Seats"
}
我的问题是:
- 为什么 ML 摄取的行为不同(来自 csv 的原始数据完全相同,只有整数)
- 我可以在摄取管道中做什么来完成它
- kibana 索引模式是否与摄取管道一样高效,或者我应该在负载等方面坚持使用摄取管道
感谢您的帮助和提示。
千比助
在摄取管道中,ctx.Seats
仍然是一个字符串,因为它是源文档中的一个字符串。您要么需要在脚本中解析它,要么在脚本之前转换它。
没有转换的选项,只是解析脚本中的值:
"script": {
"if": "!(ctx.Seats=="0") && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = 100.0 * ctx.People / Float.parseFloat(ctx.Seats)"
}
在 运行 脚本之前进行转换的选项:
{
"convert" : {
"field" : "Seats",
"type": "float",
"ignore_missing": true
}
},
{
"script": {
"if": "!(ctx.Seats==0) && !(ctx.Seats==null)",
"lang": "painless",
"source": "ctx.utilization = 100.0 * ctx.People / ctx.Seats"
}
}