Elasticsearch 在更新时附加对象字段而不是覆盖

Elasticsearch appends object fields on update instead of overwriting

我在 Elasticsearch 中有一个对象,它可能包含不同的字段。在我的应用程序中,此对象是枚举,因此它实际上不能同时包含多个字段。但是当我在 Elasticsearch 中进行更新时 - 它会附加字段而不是覆盖整个对象。

例如 - 文档可能 public 或仅供一组用户访问:

POST _template/test_template
{
  "index_patterns": [
    "test*"
  ],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "_source": {
        "enabled": true
      },
      "properties": {
        "id": {
          "type": "keyword"
        },
        "users": {
          "type": "object",
          "properties": {
            "permitted": {
              "type": "keyword"
            },
            "public": {
              "type": "boolean"
            }
          }
        }
      }
    }
  },
   "aliases" : {
      "test-alias" : { }
    }
}

POST test_doc/_doc/1
{
  "id": "1",
    "users": {
      "permitted": [
        "1", "2"
      ]
    }
}

POST _bulk
{"update":{"_index":"test_doc","_type":"_doc","_id":1}}
{"doc":{"id":"1","users":{"public": true}},"doc_as_upsert":true}

GET test-alias/_search

我期待这样的结果:

{
    "id": "1",
    "users": {
        "public": true
    }
}

但实际结果是:

{
    "id": "1",
    "users": {
        "permitted": [
            "1",
            "2"
        ],
        "public": true
    }
}

同时它完美地覆盖了具有相同名称的字段(我可以将允许的数组或 public 字段更改为 false)。如何禁用对象字段附加?

您需要将 action 批量请求从 update 更改为 index,正确的请求是

{"index":{"_index":"71908768","_id":1}}
{"doc":{"id":"1","users":{"public": true}}}

official Elasticsearch docs 中详细介绍操作及其作用。简而言之,update 部分更新文档,而索引操作索引指定的文档。 如果文档存在,则替换文档并增加版本