elasticsearch,logstash,Ruby,elasticsearch,Logstash" /> elasticsearch,logstash,Ruby,elasticsearch,Logstash" />

Ruby Logstash筛选器-将密钥名称从“转换”;这是一个“例子”=&燃气轮机;1到[这][是][示例]=>;1.

Ruby Logstash筛选器-将密钥名称从“转换”;这是一个“例子”=&燃气轮机;1到[这][是][示例]=>;1.,ruby,elasticsearch,logstash,Ruby,elasticsearch,Logstash,给定这个LogStash事件,一个ruby哈希 { "_some_private_key" => 10, "address_unit" => "1", "address_sqft" => 1098, "address_city" => "NEW YORK", "apartment_floor_unit_door" => "5", "tags" => [ "pub", "import

给定这个LogStash事件,一个ruby哈希

{
    "_some_private_key" => 10,
    "address_unit" => "1",
    "address_sqft" => 1098,
    "address_city" => "NEW YORK",
    "apartment_floor_unit_door" => "5",
    "tags" => [
        "pub",
        "importer",
        "assessment"
    ]
}
应将其存储在ES中作为

{
  "_some_private_key": 10,
  "address": {
    "unit": 1,
    "sqft": 1098,
    "city": "NEW YORK"
  },
  "apartment": {
    "floor" : {
      "unit": {
        doors: 1043
      }
    }
  },
  "tags": [
    "pub",
    "importer",
    "assessment"
  ]
}
限制条件:

  • 应绕过以
    开头的键
  • 应为动态/递归,检查钥匙
    公寓楼单元门
    示例
我想知道是否有一些内置/社区过滤器来实现它,或者如何使用ruby代码实现它

谢谢

inp = {
    "address_unit" => "1",
    "address_sqft" => 1098,
    "address_city" => "NEW YORK",
    "tags" => ["pub", "importer", "assessment"]
}

inp.inject({}) do |memo, (k, v)| 
  if k =~ /\A(.*?)_(.*)/
    (memo[$~[1]] ||= {})[$~[2]] = v
  else
    memo[k] = v
  end
  memo
end 

#⇒ {
#  "address" => {
#     "city" => "NEW YORK",
#     "sqft" => 1098,
#     "unit" => "1"
#   },
#     "tags" => [
#    [0] "pub",
#    [1] "importer",
#    [2] "assessment"
#  ]
# }

上面的代码将所有带下划线的
foo\u bar
键分解为嵌套键。

类似于mudasobwas答案,但使用
每个带对象的键。如果可能的话,我更喜欢这种方法而不是
inject
(每个带有\u对象的\u只适用于可变对象,因为在块的末尾不返回新对象)

此外,我没有使用Regexp(仅通过
.split()
间接使用),因为我认为这更具可读性)

您需要处理带有多个下划线的键吗?还是更高层次的筑巢

更新:

def convert(input)
  input.each_with_object({}) do |(key, value), output|
    next if key.start_with?('_')
    keys = key.split('_')
    convert_keys(output, keys, value)
  end
end

def convert_keys(output, keys, value)
  keys[0...-1].each do |key|
    output = output[key] ||= {}
  end
  output[keys.last] = value
end
这应该能奏效。它不是递归的(如果输入散列的值再次是需要分解的键的散列,则不起作用),因为您的示例输入不需要这样做。
convert\u keys
方法也可以递归完成。但我更喜欢这里的迭代方法

这能解决问题吗?

给出您的示例(三个字段),logstash解决方案如何:

mutate {
    rename => { "address_unit" => "[address][unit]" }
    rename => { "address_sqft" => "[address][sqft]" }
    rename => { "address_city" => "[address][city]" }
}

我没有考虑rename是否可以一次完成多个任务,所以您也可以尝试一下。

抱歉,但它需要是动态的。我更新了问题以反映实际需要。谢谢你好快到了!我更新了问题,添加了约束条件。谢谢你的帮助!你误解了它的工作原理。没有人会为你编写代码。我不会误解SO的工作原理,像你这样的人正在破坏SO,也知道删除我的旧评论不会改变它;)帕斯卡,谢谢你的回答!我没有指定它需要是动态的。我用更多的信息更新了这个问题,包括约束条件。您的代码就快到了,它只需要是动态/递归的。你还能帮忙吗?谢谢非常感谢,你帮了很多忙!请继续这样,所以需要像你这样的人理解什么是互相帮助。所以今天是一群有知识的人,当人们去那里寻求帮助时,他们能做的就是说:在谷歌搜索,30分钟内学会,胡说!干杯,老兄,你摇滚,救了我一命**!是 啊
mutate {
    rename => { "address_unit" => "[address][unit]" }
    rename => { "address_sqft" => "[address][sqft]" }
    rename => { "address_city" => "[address][city]" }
}