# Compare a field with a csv file and add info from csv in a new field

**URL:** https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973
**Category:** Logstash
**Created:** [July 24, 2019, 7:49am UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973 "2019-07-24T07:49:15Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![theo1991](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@theo1991](https://discuss.elastic.co/u/theo1991)
#### Post date: [July 24, 2019, 7:49am UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/1 "2019-07-24T07:49:15Z")

</div>

Hello,

I have a field named id in a grok filter, which I want to compare with a CSV file. For example :  
Index ELK :

`id=12`

csv file :

```
11,home
12,garden
13,office 
...

```

How can I compare the id field with the first field of my csv, and if it matches, add a new field with the corresponding string like :

```
id=12
location=garden

```

I'm able to use translate to compare with just one information by line in a csv file and add a boolean value if it's matching :

csv file :

```
11
12
13

```

conf :

```
translate {
field => "[id]"
destination => "[location]"
dictionary_path => '/home/file.csv'
refresh_interval => '1000'
}

```

result

```
id=12
location=True

```

But I don't see how to add a field with the corresponding value. 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: [July 24, 2019, 12:34pm UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/2 "2019-07-24T12:34:26Z")

</div>

If file.csv contains

```
11,home
12,garden
13,office

```

then this configuration

```
input { generator { count => 1 lines => [''] } }

filter {
    mutate { add_field => { "id" => "12" } }
    translate {
        field => "[id]"
        destination => "[location]"
        dictionary_path => '/home/file.csv'
        refresh_interval => '1000'
    }
}
output { stdout { codec => rubydebug { metadata => false } } }

```

will produce

```
  "location" => "garden",
        "id" => "12",

```

Your filter should work as is.

---

<div class="post-metadata">

### Author: ![theo1991](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@theo1991](https://discuss.elastic.co/u/theo1991)
#### Post date: [July 24, 2019, 1:07pm UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/3 "2019-07-24T13:07:27Z")

</div>

Do I have to add all the number of id in the mutate field if I want to catch them all ? Because there are a lot of id ...

```
mutate { add_field => { "id" => "11" } 
add_field => { "id" => "12" }
add_field => { "id" => "13" }
}

```

etc ... ?

---

<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: [July 24, 2019, 1:17pm UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/4 "2019-07-24T13:17:24Z")

</div>

No, you are missing my point. I was trying to show that if the event has a field id which contains "12" then that translate filter will set [location] to "garden".

If the filter is not doing that it suggests the event does not have an [id] field.

---

<div class="post-metadata">

### Author: ![theo1991](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@theo1991](https://discuss.elastic.co/u/theo1991)
#### Post date: [August 8, 2019, 1:35pm UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/5 "2019-08-08T13:35:00Z")

</div>

So what's the correct way to do that overall ? Sorry for the delay

---

<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: [August 8, 2019, 2:33pm UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/6 "2019-08-08T14:33:21Z")

</div>

The filter you had in your initial post is the right way to do it. If it does not do the translation the only explanation I can think of is that the event does not have an [id] field.

---

<div class="post-metadata">

### Author: ![theo1991](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@theo1991](https://discuss.elastic.co/u/theo1991)
#### Post date: [August 9, 2019, 7:33am UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/7 "2019-08-09T07:33:47Z")

</div>

Thank you Badger,

I found the problem.

The field id is an array object :  
In my grok filter :

`u'ids': \[(?<[@metadata][ids]>[^\]]+)\]`

In my ruby filter :

```
ids = event.get('[@metadata][ids]')
		if ids
			id = ids.scan(/{u'type': u'([^']+)', u'id': ([0-9]+)}/)
			event.set('id', id)
		end

```

So in Kibana, it's visible like this :

["firstid", "1"]  
["secondid", "2"]

Logstash don't like this and loop restart. I'm unable to select which field I want in id.  
Edit : I try with another field which is not nested ( %{GREEDYDATA:dst-ip} ) , but it doesn't work ☹

```
translate {
		field => "[dst-ip]"
		destination => "[malicious]"
		dictionary_path => '/home/ip.csv'
		refresh_interval => '1000'
	}
```

---

<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: [September 6, 2019, 7:33am UTC](https://discuss.elastic.co/t/compare-a-field-with-a-csv-file-and-add-info-from-csv-in-a-new-field/191973/8 "2019-09-06T07:33:48Z")

</div>

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