logstash导出子表数据,es使用keyword接受,报mapper_parsing_exception错误

业务:
logstash导出子表数据,子表(其中仅有一个有用字段)与主表为多对一的关系,最后希望能够在es中形成一个字符串数组字段。
 
我的配置:

es中的mapping为:
"grade_code": {
                        "type": "keyword"
                    }


图片中显示的是我通过filter的jdbc_streaming来查询子表的grade_code


错误:
在向es导入时报错。错误信息为:
[2017-12-21T10:32:29,506][WARN ][logstash.outputs.elasticsearch] Could not index event to Elasticsearch. {:status=>400, :action=>["index", {:_id=>nil, :_index=>"resource", :_type=>"resource", :_routing=>nil}, #<LogStash::Event:0x4fdd7acb>], :response=>{"index"=>{"_index"=>"resource", "_type"=>"resource", "_id"=>"iYvqdmAB8AnNx7EIOFwy", "status"=>400, "error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse [grade_code]", "caused_by"=>{"type"=>"illegal_state_exception", "reason"=>"Can't get text on a START_OBJECT at 1:433"}}}}}
 
 
问题:
我的做法有错误吗?  在导入时我可以这样使用mapping来期望得到一个字符串数组吗?
aa.png
已邀请:

kennywu76 - wood@Ctrip

赞同来自: piggyci

没用过jdbc_streaming,只能从报错看,得到的grade_code是一个json对象,因此无法赋值给一个keyword类型。 最好下面这样配置一个output,将过滤过后的event完整打印出来,看看grade_code的格式是怎样的,这样才好判断是否中间还需要其他过滤器辅助转换成需要的数组。
output {
stdout { codec => rubydebug }
}

 

kennywu76 - wood@Ctrip

赞同来自: piggyci

@piggyci  这样过滤出来的knowledge_code是一个json object的数组,所以mapping定义改一下,不要用keyword,而是用Array of Object应该就可以了。 
 
具体的做法,在mapping定义里,类似如下定义:
PUT /myindex/
{
"settings": {},
"mappings": {
"type1": {
"properties": {
"knowledge_code": {
"properties": {
"code": {
"type": "keyword"
}
}
}
}
}
}
}
其中knowledge_code就是一个object类型,可以写入object或者object array。  内部的object包含一个code属性,类型是keyword。
 
logstash里的jdbc_streaming相应修改一下,sql里将选出的字段名称改为和object的key同一个名称,也就是范例中的code。
 
这样一来,logstash里这个event应该是可以和上面的mapping匹配,比如写入的数据可能是:
POST myindex/type1/?refresh=true
{
"knowledge_code": [
{
"code": "abc"
},
{
"code": "efg"
}
]
}

对于object array, ES内部的实现实际上是根据object的key将其展平,上面这条文档索引的时候, 是作为knowledge_code.code : ["abc", "efg"] 这样的形式索引的。 查询的时候,查knowledge_code.code这个字段就可以了。

piggyci

赞同来自:

恩恩。我试了一下,确实是这样,默认将每一个字符串格式,都转成了json对象,我还在filter中寻找可用的。。但是没什么收获

要回复问题请先登录注册