使用 document_id 将 logstash 输出到 elasticsearch;当我没有 document_id 时怎么办?
logstash output to elasticsearch with document_id; what to do when I don't have a document_id?
我有一些 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" <> "" {
解决此问题的一种方法是确保 document_id
始终可用。您可以通过在过滤器部分添加一个 UUID filter 来实现此目的,如果 document_id
字段不存在,该字段将创建该字段。
filter {
if "" in [document_id] {
uuid {
target => "document_id"
}
}
}
根据 Magnus Bäck 的建议进行了编辑。谢谢!
您接近条件性想法,但不能将其放入插件块中。改为这样做:
output {
if [document_id] {
elasticsearch_http {
host => "127.0.0.1"
document_id => "%{document_id}"
}
} else {
elasticsearch_http {
host => "127.0.0.1"
}
}
}
(但其他答案之一中使用 uuid 过滤器的建议也很好。)
对于任何添加到 elasticsearch 中的文档,如果在插入期间未指定 _id,则会自动生成。我们稍后可以使用相同的 _id 来 update/delete/search 查询,方法是使用 docinfo_fields
功能。
示例:
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}"
}
}
我有一些 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" <> "" {
解决此问题的一种方法是确保 document_id
始终可用。您可以通过在过滤器部分添加一个 UUID filter 来实现此目的,如果 document_id
字段不存在,该字段将创建该字段。
filter {
if "" in [document_id] {
uuid {
target => "document_id"
}
}
}
根据 Magnus Bäck 的建议进行了编辑。谢谢!
您接近条件性想法,但不能将其放入插件块中。改为这样做:
output {
if [document_id] {
elasticsearch_http {
host => "127.0.0.1"
document_id => "%{document_id}"
}
} else {
elasticsearch_http {
host => "127.0.0.1"
}
}
}
(但其他答案之一中使用 uuid 过滤器的建议也很好。)
对于任何添加到 elasticsearch 中的文档,如果在插入期间未指定 _id,则会自动生成。我们稍后可以使用相同的 _id 来 update/delete/search 查询,方法是使用 docinfo_fields
功能。
示例:
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}"
}
}