# Logstash - ruby script to create array of nested fields

**URL:** <https://discuss.elastic.co/t/logstash-ruby-script-to-create-array-of-nested-fields/200312>\
**Category:** Logstash\
**Created:** [September 19, 2019, 9:01pm UTC](https://discuss.elastic.co/t/logstash-ruby-script-to-create-array-of-nested-fields/200312 "2019-09-19T21:01:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adithyaram](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/adithyaram/32/90794_2.png) [@Adithyaram](https://discuss.elastic.co/u/Adithyaram)\
**Post date:** [September 19, 2019, 9:01pm UTC](https://discuss.elastic.co/t/logstash-ruby-script-to-create-array-of-nested-fields/200312/1 "2019-09-19T21:01:44Z")

</div>

Hello,

I currently have the below JSON structure

```
"Unit": {
						"Unit": ["QA", "FA"],
						"QTY": ["2", "5"],
						"ID": ["1", "2"],
						"Item": ["Shirt", "Trousers"],
						"Price": ["10", "50"]
					}

```

and want to write a logstash script to to break the array of values to represent it like below :

"Unit": {  
{  
"Unit": "QA",  
"QTY": "2",  
"ID": "1",  
"Item": "Shirt",  
"Price": "10"  
},  
{  
"Unit": "FA",  
"QTY": "5",  
"ID": "2",  
"Item": "Trousers",  
"Price": "50"  
}  
}

Is there an efficient approach to solve this ? I believe this could be solved by ruby filter plugin after going through a few links like : [Indent any json file nested fields and make it flat](https://discuss.elastic.co/t/indent-any-json-file-nested-fields-and-make-it-flat/194447). Could this also be solved in any other way other than writing a ruby script ?

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [September 19, 2019, 10:50pm UTC](https://discuss.elastic.co/t/logstash-ruby-script-to-create-array-of-nested-fields/200312/2 "2019-09-19T22:50:08Z")

</div>

I was really surprised at how ugly the code I wrote to do this is. I feel there should be a much easier way.

```
    ruby {
        code => '
            a = []
            u = event.get("Unit")
            h1 = {}
            h2 = {}

            u.each { |k,v|
                h1[k] = v[0]
                h2[k] = v[1]
            }
            a << h1
            a << h2
            event.set("MonsiuerSpalanzani", a)
        '
        remove_field => ["Unit"]
    }
    split { field => "MonsiuerSpalanzani" }
    ruby {
        code => '
            event.get("MonsiuerSpalanzani").each { |k,v|
                event.set(k, v)
            }
        '
        remove_field => ["MonsiuerSpalanzani"]
    }

```

Hmm. Thinking about it, this would be much cleaner if done as a ruby script file, since that can return an array of events, so the split would not be needed. If you create a file called invertUnits.rb containing

```
def register(params)
    @field = params['field']
end

def filter(event)
    newEvents = []

    o = event.get(@field)
    if !o
      newEvents << event
    else
      (0..1).each { |n|
        e = LogStash::Event.new
        o.each { |k, v|
          e.set(k, v[n])
        }

        ["@timestamp", "@version", "host", "sequence"].each { |k|
          v = event.get(k)
          if v
            e.set(k, v)
          end
        }

        newEvents << e
      }
    end

    newEvents
end

```

then call it using

```
    ruby {
        path => "/home/user/invertUnits.rb"
        script_params => { "field" => "Unit" }
    }
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [October 17, 2019, 10:50pm UTC](https://discuss.elastic.co/t/logstash-ruby-script-to-create-array-of-nested-fields/200312/3 "2019-10-17T22:50:15Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
