Create array of objects in ruby

Hello,

I use logstash 7.17.

I want to create an array of objects in ruby from my data, now I get a list of objects. I didn't success to implement a each loop, so there is a lot of duplicate ligns. Here is a snippet of my code :

filter { 
  ruby {
        code => '
		item_id_0 = event.get("[movmentItem][0][infos][_id]")
		item_id_1 = event.get("[movmentItem][1][infos][_id]")
		item_type_0 = event.get("[movmentItem][0][itemType]")
		item_type_1 = event.get("[movmentItem][1][itemType]")
		item_date = event.get("[date]")
		item_type_u1_0 = event.get("[movmentItem][0][user_1][partyRoleType][categoryType]")
		item_type_u2_0 = event.get("[movmentItem][0][user_2][partyRoleType][categoryType]")
		item_id_u1_0 = event.get("[movmentItem][0][user_1][_id]")
		item_id_u2_0 = event.get("[movmentItem][0][user_2][_id]")
		item_type_u1_1 = event.get("[movmentItem][1][user_1][partyRoleType][categoryType]")
		item_type_u2_1 = event.get("[movmentItem][1][user_2][partyRoleType][categoryType]")
		item_id_u1_1 = event.get("[movmentItem][1][user_1][_id]")
		item_id_u2_1 = event.get("[movmentItem][1][user_2][_id]")
		
		if item_id_0 != nil
			event.set("[Movments][0][c][id]", "#{item_id_0}")
		end
		if item_id_1 != nil
			event.set("[Movments][1][c][id]", "#{item_id_1}")
		end
		if item_type_0 != nil
			event.set("[Movments][0][c][type]", "#{item_type_0}")
		end
		if item_type_1 != nil
			event.set("[Movments][1][c][type]", "#{item_type_1}")
		end
		if item_date != nil
			event.set("[Movments][0][c][date]", "#{item_date}")
			event.set("[Movments][1][c][date]", "#{item_date}")
		end
		if item_type_u1_0 != nil
			event.set("[Movments][0][a][type]", "#{item_type_u1_0}")
		end
		if item_type_u2_0 != nil
			event.set("[Movments][0][b][type]", "#{item_type_u2_0}")
		end
		if item_id_u1_0 != nil
			event.set("[Movments][0][a][id]", "#{item_id_u1_0}")
		end
		if item_id_u2_0 != nil
			event.set("[Movments][0][b][id]", "#{item_id_u2_0}")
		end
		if item_type_u1_1 != nil
			event.set("[Movments][1][a][type]", "#{item_type_u1_1}")
		end
		if item_type_u2_1 != nil
			event.set("[Movments][1][b][type]", "#{item_type_u2_1}")
		end
		if item_id_u1_1 != nil
			event.set("[Movments][0][a][id]", "#{item_id_u1_1}")
		end
		if item_id_u2_1 != nil
			event.set("[Movments][1][b][id]", "#{item_id_u2_1}")
		end
		'
        }
[...]
}

Here is my input in json :

[
	{
		"date": "2024-06-04T14:46:48.722Z",
		"movmentItem"=> [
			{
				"infos": {
					"_id": "124AB567",
				},
				"itemType": "ITEM_24",
				"user_1": {
					"_id": "TEST1234",
					"partyRoleType": { "categoryType": "type_a" }
				},
				"user_2": {
					"_id": "TEST5678",
					"partyRoleType": {
						"categoryType": "type_b"
					}
				}
			},
			{
				"infos": {
					"_id": "901XY234",
				},
				"itemType": "ITEM_82",
				"user_1": {
					"_id": "TOTO1234",
					"partyRoleType": { "categoryType": "type_a" }
				},
				"user_2": {
					"_id": "TOTO5678",
					"partyRoleType": {
						"categoryType": "type_b"
					}
				}
			}
		]
	}
]

Here is what I get right now :

"Movments" => {
	"0" => {
		"a" => {
			"type" => "type_a",
			"id" => "TEST1234"
		},
		"b" => {
			"type" => "type_b",
			"id" => "TEST5678"
		},
		"c" => {
			"type" => "ITEM_24",
			"id" => "124AB567",
			"date" => "2024-06-04T14:46:48.722Z"
		}
	},
	"1" => {
		"a" => {
			"type" => "type_a",
			"id" => "TOTO1234"
		},
		"b" => {
			"type" => "type_b",
			"id" => "TOTO5678"
		},
		"c" => {
			"type" => "ITEM_82",
			"id" => "901XY234",
			"fieldSpecial" => "2024-06-04T14:46:50.722Z"
		}
	}
}

Here is what I want :

"Movments" => [
	{
		"a" => {
			"type" => "type_a",
			"id" => "TEST1234"
		},
		"b" => {
			"type" => "type_b",
			"id" => "TEST5678"
		},
		"c" => {
			"type" => "ITEM_24",
			"id" => "124AB567",
			"date" => "2024-06-04T14:46:48.722Z"
		}
	},
	{
		"a" => {
			"type" => "type_a",
			"id" => "TOTO1234"
		},
		"b" => {
			"type" => "type_b",
			"id" => "TOTO5678"
		},
		"c" => {
			"type" => "ITEM_82",
			"id" => "901XY234",
			"fieldSpecial" => "2024-06-04T14:46:50.722Z"
		}
	}
]

Any help would be appreciated, thank you in advance

You could try something like

    json { source => "message" target => "[@metadata][json]" remove_field => [ "message" ] }
    ruby {
        code => '
            json = event.get("[@metadata][json][0]")
            movments = []

            json["movmentItem"].each_with_index { |i, x|
                h = {}

                h["a"] = {
                    "type" => i["user_1"]["partyRoleType"]["categoryType"],
                    "id" => i["user_1"]["_id"]
                }

                h["b"] = {
                    "type" => i["user_2"]["partyRoleType"]["categoryType"],
                    "id" =>   i["user_2"]["_id"]
                }

                h["c"] = {
                    "type" => i["itemType"],
                    "id" =>   i["infos"]["_id"],
                    "date" => json["date"]
                }
                movments << h
            }
            event.set("Movments", movments)
        '
    }
1 Like

Your proposition worked for me thank you, I have an additional question:
I don't understand why when I get :

"Movments" => [
      [0] {
              "a" => {
                      "type" => "type_a",
                       "id" => "TEST1234"
              },
              "b" => {
                       "type" => "type_b",
                       "id" => "TEST5678"
              },
              "c" => {
                      "type" => "ITEM_24",
                      "id" => "124AB567",
                      "date" => "2024-06-04T14:46:48.722Z"
              }
      },
      [1] {
              "a" => {
                      "type" => "type_a",
                      "id" => "TOTO1234"
              },
              "b" => {
                      "type" => "type_b",
                      "id" => "TOTO5678"
              },
              "c" => {
                      "type" => "ITEM_82",
                      "id" => "901XY234",
                      "fieldSpecial" => "2024-06-04T14:46:50.722Z"
              }
      }
]

It drop with this condition

if (![Movments][0]) {
        drop {
                id => "Empty_movment"
        }
} 

We are looking for the first element in the array Movments and there is one, so I don't get why it doesn't work. Do you have some ideas ?