# Pair key with multiple values from different fields

**URL:** <https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693>\
**Category:** Logstash\
**Created:** [March 4, 2019, 9:36am UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693 "2019-03-04T09:36:15Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Petr.Simik](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/petr.simik/32/38082_2.png) [@Petr.Simik](https://discuss.elastic.co/u/Petr.Simik)\
**Post date:** [March 4, 2019, 9:36am UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/1 "2019-03-04T09:36:15Z")

</div>

pair key with multiple values from different fields

I am looking for method how to pair BUCKET with COSTS and BALANCE the source:

> ...  
> "BUCKETS": "BUCKET1,BUCKET2,name:BUCKET3,... {n BUCKETs}"  
> "COSTS": "10,20,30,price:10,....."  
> "BALANCES":"1000,2000,3000,...."  
> ...

list of keys and values is dynamic and vary from 0..n values (max appx.15)

I want result like:

> BUCKET1:{COST:10,BALANCE:1000}  
> BUCKET2:{COST:20,BALANCE:2000}  
> BUCKET3:{COST:30,BALANCE:3000}  
> ..

(the reason I want to be able to create sum/average reports on COSTS, BALANCE fields.)

I tried to create array from string

> mutate {  
> split =\> ["BUCKETS",","]  
> split =\> ["BALANCES",","]  
> split =\> ["COSTS",","]  
> }

and then ruby code to iterate over and pair Bucket to cost and balance:  
event.get('BUCKETS').each do |bucket|  
..  
but I do not know how to iterate over multiple arrays within one loop  
I thought using  
event.get('BUCKETS').length and than iterate for loop but not found solution

i tried this approach works in ruby but not in logstash

> ```
> bucket= event.get('BUCKETS').each
> cost = event.get('COSTS').each
> balance = event.get('BALANCES').each
> loop do
> balance_type = balance_type.next
> cost = cost.next
> balance = balance.next
> 
> ```
> 
> ...

Thank you for any advice. Would you do it with ruby or any other filter?

---

<div class="post-metadata">

**Author:** ![paz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paz/32/28003_2.png) [@paz](https://discuss.elastic.co/u/paz)\
**Post date:** [March 4, 2019, 10:43am UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/2 "2019-03-04T10:43:56Z")

</div>

Ruby filter is probably the most (or only) appropriate approach. Assuming the corresponding values are in order, and your input looks like this:

```auto
{
	"BUCKETS": "BUCKET1,BUCKET2,BUCKET3",
	"COSTS": "10,20,30",
	"BALANCES": "1000,2000,3000"
}
```

You can do what you need with the following snippet.  
(I opted to split them inside the Ruby block since you can skip using an extra `mutate` block.

```auto
ruby {
    code => "
        buckets, costs, balances = event.get('BUCKETS').split(','), event.get('COSTS').split(','), event.get('BALANCES').split(',')
        buckets.each_index { |i| event.set(buckets[i], Hash['COST',costs[i],'BALANCE',balances[i]])}
    "
}
```

This will produce an event like this:

```auto
{
    ...,
    "BUCKET1" => {
	"BALANCE" => "1000",
	"COST" => "10"
    },
    "BUCKET2" => {
	"BALANCE" => "2000",
	"COST" => "20"
    },
    "BUCKET3" => {
	"BALANCE" => "3000",
	"COST" => "30"
    },
    ....
}
```

---

<div class="post-metadata">

**Author:** ![Petr.Simik](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/petr.simik/32/38082_2.png) [@Petr.Simik](https://discuss.elastic.co/u/Petr.Simik)\
**Post date:** [March 4, 2019, 4:42pm UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/3 "2019-03-04T16:42:13Z")

</div>

@paz Great thank you exactly what I was looking for . 👍👍👍

---

<div class="post-metadata">

**Author:** ![Petr.Simik](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/petr.simik/32/38082_2.png) [@Petr.Simik](https://discuss.elastic.co/u/Petr.Simik)\
**Post date:** [March 11, 2019, 6:00am UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/4 "2019-03-11T06:00:41Z")

</div>

@paz would you give me one more hint?  
I was thinking to change the structure from this:

> {  
> ...,  
> "BUCKET1" =\> {  
> "BALANCE" =\> "1000",  
> "COST" =\> "10"  
> },  
> "BUCKET2" =\> {  
> "BALANCE" =\> "2000",  
> "COST" =\> "20"  
> },  
> "BUCKET3" =\> {  
> "BALANCE" =\> "3000",  
> "COST" =\> "30"  
> },  
> ....  
> }

to this

> {  
> ..,  
> "COST" =\> {  
> BUCKET1 = 10,  
> BUCKET2 = 20,  
> BUCKET3 = 30  
> },  
> "BALANCE" =\> {  
> BUCKET1 = 100,  
> BUCKET2 = 200,  
> BUCKET3 = 300  
> },  
> ...  
> }

If I modified the code (added 2 lines event.set for reference kept also original event.set)

> ruby {  
> code =\> "  
> buckets, costs, balances = event.get('BUCKETS').split(','), event.get('COSTS').split(','), event.get('BALANCES').split(',')  
> buckets.each\_index { |i|  
> event.set(buckets[i], Hash['COST',costs[i],'BALANCE',balances[i]])  
> event.set('BALANCE', Hash[buckets[i],balances[i].to\_i])  
> event.set('COST', Hash[buckets[i],costs[i].to\_i])  
> }  
> "  
> }

however event.set replaces previous event.set. I supposed it will add new event since it has same parent COST with different inside. But it does not work this way.

How would you change the code to get the new result?  
thank you

---

<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:** [March 11, 2019, 1:03pm UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/5 "2019-03-11T13:03:43Z")

</div>

```
    mutate { split => { "BALANCES" => "," "BUCKETS" => "," "COSTS" => "," } }
    ruby {
        code => '
            balances = event.get("BALANCES")
            buckets = event.get("BUCKETS")
            costs = event.get("COSTS")
            balance = {}
            cost = {}
            buckets.each_index { |x|
                k = buckets[x]
                cost["#{k}"] = costs[x]
                balance["#{k}"] = balances[x]
            }
            event.set("COST", cost)
            event.set("BALANCE", balance)
        '
    }
```

---

<div class="post-metadata">

**Author:** ![Petr.Simik](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/petr.simik/32/38082_2.png) [@Petr.Simik](https://discuss.elastic.co/u/Petr.Simik)\
**Post date:** [March 12, 2019, 5:19am UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/6 "2019-03-12T05:19:20Z")

</div>

@Badger thank you, it helped 👍👍

how does this code works?

> cost["#{k}"]

---

<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:** [March 12, 2019, 12:39pm UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/7 "2019-03-12T12:39:30Z")

</div>

In Ruby that is called string interpolation. Inside double quotes (but not single quotes) you can use #{x} to substitute the value of variable x.

---

<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:** [April 9, 2019, 12:39pm UTC](https://discuss.elastic.co/t/pair-key-with-multiple-values-from-different-fields/170693/8 "2019-04-09T12:39:34Z")

</div>

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