仅更新elasticsearch中的特定字段值

Joh*_*lip 22 indexing search elasticsearch

是否可以更新elasticsearch中的某些特定字段值而不覆盖其他字段.?

Mar*_*arc 40

在 ES 7.3 中,新格式是:

POST /myindex/_update/mydocid
{
    "doc" : {
        "myfield": "new value of my field"
    }
}
Run Code Online (Sandbox Code Playgroud)


ped*_*uan 27

作为对此答案的基于代码的贡献,可以使用以下查询:

POST /index/type/100100471/_update
{
    "doc" : {
        "yourProperty" : 10000
    }
}
Run Code Online (Sandbox Code Playgroud)

此查询yourProperty 更新属性.

结果,出现此响应:

{
   "_index": "index",
   "_type": "type",
   "_id": "100100471",
   "_version": 1,
   "_shards": {
      "total": 0,
      "successful": 1,
      "failed": 0
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 我收到`验证失败:1:脚本或文档丢失;` - 知道为什么吗? (3认同)
  • @rahulg 没有类型的新语法是 POST /yourindexname/_update/youridnumber { "doc" : { "yourProperty" : 10000 } } (3认同)

jav*_*nna 20

是的,Elasticsearch支持部分更新.这意味着您可以提交:

  • 部分文档,将与现有文档合并
  • 将在现有文档之上执行的脚本

看看更新api.在这两种情况下,由于底层lucene库的工作方式,在幕后发生的事情是检索要更新的文档,对其应用更改,并使用新文档覆盖旧文档.在一天结束时,它实际上是对文档的完全重写,但您不必提交整个文档,除非您禁用_source字段,默认情况下启用,这是允许您检索到的字段整个文档,以便对其进行更改.


Pra*_*H G 10

通过查询更新 API

更新与指定查询匹配的文档。如果未指定查询,则对数据流或索引中的每个文档执行更新,而不修改源,这对于获取映射更改非常有用。

POST http://localhost:9200/INDEX_NAME/_update_by_query
{
  "script": {
    "source": "ctx._source.userName=new_user_name",
    "lang": "painless"
  },
  "query": { 
    "term": {
      "userName": "old_user_name"
    }
  }
}   
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,userName 字段值将更新为 new_user_name


小智 8

如果您只想更新现有字段值,则必须尝试以下解决方案:

POST IndexName/_update_by_query
{
  "script": {
    "source": """

   if (ctx._source?.Field != null) 
    {  
        ctx._source.remove('Field');
        ctx._source.put('Field', 'Value');
    }   
    """,
    "lang": "painless"
  },
  "query": {
    "terms": {
        "_id": [
          1 (Replace with Document ID)
        ]
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您想添加具有值的新字段,则必须尝试以下解决方案:

POST IndexName/_update_by_query
{
  "script": {
    "source": """

   if (ctx._source?.NewField == null) 
    {  
        ctx._source.hf.put('NewField', 'Value');
    }   
    """,
    "lang": "painless"
  },
  "query": {
    "terms": {
        "_id": [
          1 (Replace with Document ID)
        ]
      }
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您还可以使用批量更新来部分更新多个文档

POST /foo_v1/_bulk?pretty=true&error_trace=true
{"update":{"_index":"foo_v1","_type":"footype","_id":"397"}}
{"doc":{"Name":"foo","EmailId":"foo@test.com"}}
{"update":{"_index":"foo_v1","_type":"footype","_id":"398"}}
{"doc":{"Name":"foo1","EmailId":"foo1@test.com"}}
Run Code Online (Sandbox Code Playgroud)

如果您不确定它是更新还是像 Upsert 那样插入,您可以执行以下操作:

POST /foo_v1/_bulk?pretty=true&error_trace=true
{"update":{"_index":"foo_v1","_type":"footype","_id":"397"}}
{"doc":{"Name":"foo","EmailId":"foo@test.com"}, "doc_as_upsert" : true}
Run Code Online (Sandbox Code Playgroud)

使用“doc_as_upsert”:true


kri*_*hna 5

拨打POST电话至{{host}}/{{index}}/_doc/{{id}}/_update

身体作为

{
    "doc": {
        "field": "value"
    }
}
Run Code Online (Sandbox Code Playgroud)

输出类似于

{
    "_index": "{{index}}",
    "_type": "_doc",
    "_id": "{{id}}",
    "_version": 3,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 27,
    "_primary_term": 2
}
Run Code Online (Sandbox Code Playgroud)

  • 此 URL 的结尾应为“...{{index}}/_update/1”。您的替代方案仍然适用于 ES 7,但涉及“_doc”端点的所有内容在 ES 8 中都将变得非法!Marc 在 2019 年的回答已经给出了面向未来的答案。你应该删除你的。 (3认同)