【问题标题】:Elasticsearch remove a field from an object of an array in a dynamically generated indexElasticsearch 从动态生成的索引中的数组对象中删除字段
【发布时间】:2020-07-15 11:34:43
【问题描述】:

我正在尝试从 Elasticsearch 中的数组对象中删除字段。索引是动态生成的。

这是映射:

{
  "mapping": {
    "_doc": {
      "properties": {
        "age": {
          "type": "long"
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "result": {
          "properties": {
            "resultid": {
              "type": "long"
            },
            "resultname": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            }
          },
        "timestamp": {
          "type": "date"
        }
      }
    }
  }
}
}

这是一份文件:

{
    "result": [
        {
            "resultid": 69,
            "resultname": "SFO"
        },
        {
            "resultid": 151,
            "resultname": "NYC"
        }
    ],
    "age": 54,
    "name": "Jorge",
    "timestamp": "2020-04-02T16:07:47.292000"
}

我的目标是删除索引的所有文档中导致结果的所有字段。更新后的文档应该是这样的:

{
    "result": [
        {
            "resultname": "SFO"
        },
        {
            "resultname": "NYC"
        }
    ],
    "age": 54,
    "name": "Jorge",
    "timestamp": "2020-04-02T16:07:47.292000"
}

我尝试在 stackoverflow 上使用以下文章,但没有成功: Remove elements/objects From Array in ElasticSearch Followed by Matching Query remove objects from array that satisfying the condition in elastic search with javascript api Delete nested array in elasticsearch Removing objects from nested fields in ElasticSearch

希望有人能帮我找到解决办法。

【问题讨论】:

    标签: elasticsearch elasticsearch-painless


    【解决方案1】:

    您应该使用_reindex API 在新索引中重新索引您的索引并调用脚本来删除您的字段:

    POST _reindex
    {
      "source": {
        "index": "my-index"
      },
      "dest": {
        "index": "my-index-reindex"
      },
      "script": {
        "source": """
         for (int i=0;i<ctx._source.result.length;i++) {
            ctx._source.result[i].remove("resultid")
         }
         """
    
      }
    }
    

    在你可以删除你的第一个索引之后:

    DELETE my-index
    

    并重新索引它:

    POST _reindex
    {
      "source": {
        "index": "my-index-reindex"
      },
      "dest": {
        "index": "my-index"
      }
    }
    

    【讨论】:

    • 非常感谢!我将您的脚本与“通过查询更新”一起使用,因此我没有重新索引
    • 完美!在新索引中重新索引更安全。你能把我的答案标记为已解决吗
    • 我同意重新索引到新索引更安全,因此如果出现问题,您将始终拥有旧索引。
    【解决方案2】:

    我将 Luc E 的答案与我自己的一些知识结合起来,以便在不重新索引的情况下找到解决方案。

    POST INDEXNAME/TYPE/_update_by_query?wait_for_completion=false&conflicts=proceed
    
    {
    "script": {
        "source": "for (int i=0;i<ctx._source.result.length;i++) { ctx._source.result[i].remove(\"resultid\")}"
        },
    "query": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "result.id"
              }
            }
          ]
        }
      }
    }
    

    再次感谢卢克!

    【讨论】:

      【解决方案3】:

      如果您的数组有多个要删除的元素副本。用这个: ctx._source.some_array.removeIf(tag -&gt; tag == params['c'])

      【讨论】:

        猜你喜欢
        • 2021-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多