I have a Json something like this , I trying to flatten it before storing in Elasticsearch. all nested elements should be on level 1. I read about ruby script. I am new to ELK and ruby. someone can help me out?
@Badger Thanks, I am already using this for JSON Object. Before that, I need to flatten array. With this link, my JSON object is getting flatten but it doesn't work on an array.
Also the above link we need to pass each field, imagine Json with ten inner JSON object we need to call ten times.
Just help me in iterating array dynamically and getting a key.
This is my plan.
Get all array dynamically
Iterate them and use the above link to flatten JSON
Repeat it for all.
I am new this, I just started exploring from last few days.
Thanks
First run the split over user and then another split over subject. This will give you one event per user per subject and then use @Badger's code to recursively process the hashes.
filter {
json{
source => "message"
}
split{
field => "user"
}
split{
field => "[user][subject]"
}
# code to process the hashes recursively here
}
What is your end goal? If you flatten this data you will lose the object relations as @Badger mentioned. Also, can you please share the mapping if you are using one?
@Rahul_Kumar4 Thanks.
This looks simpler and easy approach. Unfortunately, there are few challenges
Split on multiple fields at the same level not working ( user and address, both are arrays and same level). Need to figure it out.
When I tried field =>[user][address] I get an error Only String and Array types are splittable. field:[user][address] is of type = NilClass
When I split array I get {"k":"v"} and @Badger function needs field name to be passed "fn":{"k":"v"} to flatten it .
I am still figuring out the right approach
I just want to bring all nested keys to the first level. Technically just one { and one }.
Trying to see if it is possible to achieve. When there are two arrays it is getting complicated.
@all, when we use a split filter, does it creates two output out of one json input data? In my case, it is inserting two records with the same data except for the split keys in the elastic search.
In this case I need to call twice with A and B. I made small change in the ruby script (from your link) and able to process by sending comma separated values Sharing for future readers
def register(params)
@field = params['field']
end
def flatten(object, name, event)
if object
if object.kind_of?(Hash) || object == {} || object==[]
object.each { |k, v| flatten(v, "#{name}.#{k}", event) }
else
event.set(name, object)
end
end
end
def filter(event)
inputs = @field.split(',')
for input in inputs
o = event.get(input)
if o
flatten(o, input, event)
end
event.remove(input)
end
[event]
end
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.