我有一些logstash输入,我使用document_id
来删除重复项。但是,大多数输入没有document_id
。以下是实际的document_id
直通,但是如果它不存在,它将被接受为字面%{document_id}
,这意味着大多数文档被视为彼此的副本。这是我的输出块的样子:
output {
elasticsearch_http {
host => "127.0.0.1"
document_id => "%{document_id}"
}
}
我以为我可以在输出中使用条件。它失败了,错误在代码下面给出。
output {
elasticsearch_http {
host => "127.0.0.1"
if document_id {
document_id => "%{document_id}"
}
}
}
Error: Expected one of #, => at line 101, column 8 (byte 3103) after output {
elasticsearch_http {
host => "127.0.0.1"
if
我尝试了一些“if”语句并且它们都失败了,这就是为什么我认为问题是在该块中有任何排序的条件。以下是我尝试过的替代方案:
if document_id <> "" {
if [document_id] <> "" {
if [document_id] {
if "hello" <> "" {
答案 0 :(得分:9)
你接近条件的想法,但你不能把它放在一个插件块中。这样做:
output {
if [document_id] {
elasticsearch_http {
host => "127.0.0.1"
document_id => "%{document_id}"
}
} else {
elasticsearch_http {
host => "127.0.0.1"
}
}
}
(但是使用uuid过滤器的其他一个答案中的建议也很好。)
答案 1 :(得分:5)
解决此问题的一种方法是确保document_id
始终可用。您可以通过在过滤器部分中添加UUID filter来实现此目的,如果该字段不存在,则会创建document_id
字段。
filter {
if "" in [document_id] {
uuid {
target => "document_id"
}
}
}
根据MagnusBäck的建议编辑。谢谢!
答案 2 :(得分:0)
对于在 elasticsearch 中添加的任何文档,如果在插入期间未指定,_id 将自动生成。我们可以稍后通过使用 docinfo_fields
功能使用相同的 _id 来更新/删除/搜索查询。
示例:
filter {
json {
source => "message"
}
elasticsearch {
hosts => "http://localhost:9200/"
user => elastic
password => elastic
query => "..."
docinfo_fields => {
"_id" => "docid"
"_index" => "document_index"
}
}
if ("_elasticsearch_lookup_failure" not in [tags]) {
#... doc update logic ...
}
}
output {
elasticsearch {
hosts => "http://localhost:9200/"
user => elastic
password => elastic
index => "%{document_index}"
action => "update"
doc_as_upsert => true
document_id => "%{docid}"
}
}