当前位置: 首页 > 知识库问答 >
问题:

是否在所有查询匹配文档中添加新的不存在的嵌套字段?

彭礼骞
2023-03-14

我使用的是ELK 7.12。
我的外部json

{"req-id":"Test9","process-code":"demo9","field1":1,"field2":"abc"}

Elasticsearch文档:

{"docid":"...", "h":{...},"a":{...}}

预期产出:

{"docid":"...", "h":{...},"a":{...}, "externaldata":{"field1":1,"field2":"abc"}}

Logstash管道:

filter {
    elasticsearch {
        hosts => "http://localhost:9200/"
        user => elastic
        password => elastic
        index => "demo7"
        query => "h.req-id:%{[req-id]} AND h.process-code:%{[process-code]}"
        docinfo_fields => {
          "_id" => "docid"
        }
    }
    if ("_elasticsearch_lookup_failure" not in [tags]) {
        mutate {
            add_field => {"externaldata"=>{}}
            add_field => { "externaldatafield1" => "%{[field1]}" }
            add_field => { "externaldatafield2" => "%{[field2]}" }
        }
        mutate {
            rename => {
                "externaldatafield1" => "[externaldata][field1]"
                "externaldatafield2" => "[externaldata][field2]"
            }
        }
    }
}
output {
    elasticsearch {
        hosts => "http://localhost:9200/"
        user => elastic
        password => elastic
        index => "demo7"
        action => "update"
        doc_as_upsert => true
        document_id => "%{docid}"
    }
}

错误:

"error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse field [externaldata] of type [text] in document with id '901'. Preview of field's value: '{field1=1, field2=abcd}'"

我尝试了其他SO文章中的一些组合,以在事件中添加嵌套字段,但管道未能执行。请给我提供正确的语法。我的学习参考是这个。

编辑1:
根据leandrojmp的注释,GET /demo7/_mapping的结果是:

"externaldata" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }

在研究映射概念之后,我删除了索引并成功地重新执行了管道

现在的问题是,仅更新两个查询匹配文档中的一个。如何使用externaldata字段更新所有查询匹配文档?如果我应该使用任何循环/跳转代码,请提供参考?

编辑2:
我最初关于附加字段和映射错误的问题由leandrojmp解决;因此接受了他们的回答。但多文档更新问题仍然存在。到目前为止,我理解应该使用“http”或“exec”插件而不是“elasticsearch”。

共有1个答案

金令
2023-03-14

此错误意味着您的索引中已有一个文档,其中externaldata字段的类型为text,现在您正试图为对象的同一字段编制索引。

例如,如果在一个文档中有externaldata作为文本:

{ 
    "externaldata": "some string text value" 
}

在其他文档中,您有externaldataas和object:

{ 
    "externaldata": {
        "field1": "1",
        "field2": "2"
    }
}

这两个文档中的一个将被拒绝,这取决于您的映射。如果您没有明确应用映射,elasticsearch将使用它首先接收的类型为字段创建映射,在您的情况下,该类型似乎是文本类型。

要解决此问题,您需要删除索引,并为字段externaldata应用映射,或为该字段为对象的文档编制索引。

映射如下所示:

{
    "externaldata": {
        "properties: {
            "field1": { "type": "keyword" },
            "field2": { "type": "keyword" }
        }
    }   
} 

如果在您的数据中,您有此字段不是对象的文档,您将需要更改其名称,您不能将相同的字段作为字符串和对象。

另外,你的变异过滤器是错误的,你只需要这样的东西:

mutate {
    add_field => { "[externaldata][field1]" => "%{[field1]}" }
    add_field => { "[externaldata][field2]" => "%{[field2]}" }
}

 类似资料:
  • 我是Elasticsearch的新手,我提出了一个问题,Elasticsearch嵌套查询是否只能为嵌套字段返回匹配的嵌套文档。 对于示例,我有一个名为的类型,其中嵌套字段名为 和嵌套查询 我需要的是搜索有提到足球的评论的博客文章,每个博客文章的评论数与足球相匹配(在例子中它数为1,因为另一个评论刚刚提到篮球)。 然而,Elasticsearch似乎总是返回完整的文档,所以我如何才能实现它,或者我

  • 假设模型: 由于用户是“嵌套”类型,我想使用多匹配查询来选择在父级和内部层匹配的匹配文档(和内部命中)。 搜索应该给我上面的文档以及所有内部命中,因为它在父级别上完全匹配。 搜索应该会给我上面的文档,但只与第一个内部命中匹配,因为它在父级上不匹配,也与第二个内部命中不匹配。 搜索<code>粉丝Smith</code>应该会给我上面的文档,但只有第一个内部命中,因为组合结果与父字段和第一个内部击中

  • 问题内容: 我有这样的ES文档。 现在我想在此文档中添加一个新的“注释”,最后该文档将是 我不想在每次追加过程中都提供现有的“ comments”对象,因此最好是每次向此嵌套字段添加新对象的最佳方法。 我的解决方案: 问题答案: 检查脚本本身中的空字段。如果该字段不存在,则首先创建

  • 我正在尝试捕获异常,但无效。以下是我视图中的代码: 我还尝试了:“除了act_edit.DoesNotExist:”但错误仍然存在“活动匹配查询不存在”。你知道吗? 谢谢

  • 假设我有 100 个带字段的文档 地址 现在假设我的业务模式正在改变,我想添加新的现场呼叫。 如何在所有100个文档中添加?NoSQL数据库上有这样的东西吗?

  • 基本问题如下:有没有一种方便的方法可以为嵌套查询的所有字段指定多字段匹配?对于普通查询有效。这在嵌套查询中不起作用,可能是因为嵌套对象没有_all? 下面是更详细的问题: 我有一个名为“Parent”的嵌套文档,如下所示: 这是我用于制作儿童嵌套对象的映射: 这是一个查询,我想使用所有子字段的匹配来选择几个术语查询,以及一个术语查询: 上述查询不起作用,因为我无法为嵌套对象选择多匹配查询中的所有字