仅更新elasticsearch中的特定字段值

时间:2013-10-24 10:20:25

标签: search indexing elasticsearch

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

7 个答案:

答案 0 :(得分:18)

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

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

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

答案 1 :(得分:18)

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

POST /index/type/100100471/_update
{
    "doc" : {
        "yourProperty" : 10000
    }
}

此查询仅更新yourProperty 属性

结果,出现了这个回复:

{
   "_index": "index",
   "_type": "type",
   "_id": "100100471",
   "_version": 1,
   "_shards": {
      "total": 0,
      "successful": 1,
      "failed": 0
   }
}

答案 2 :(得分:3)

在ES 7.3中,新格式为:

#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
template<typename Arg> 
void func(Arg* arg) 
{  
    arg();
}
template<typename Arg, typename... Args> 
void func(Arg arg, Args... args) 
{  
    func(args...);
    arg();
}
template<typename Container> 
void func(Container&& c) 
{
    for (typename Container::reverse_iterator i = c.rbegin(); i != c.rend(); ++i ) 
    { 
        (*i)();
    } 
    //OR Which is bettere to use
    /*for(auto && e : c){
        e();
    }*/
}

void f()
{
    std::cout << "+" ;
}

int main()
{
    //1
    func(f,f,f);

    //2    
    std::vector<std::function<void()> > v{f,f};
    func(std::move(v));
}

答案 3 :(得分:1)

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

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"}}

如果不确定是更新还是类似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}

使用“ doc_as_upsert”:是

答案 4 :(得分:0)

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

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)
        ]
      }
  }
}

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

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)
        ]
      }
  }
}

答案 5 :(得分:0)

尝试一下

curl -XPOST --header 'Content-Type: application/json' https://search-testarticle-2cwv6oh7wtz3hxowgxv3rprnsa.ap-south-1.es.amazonaws.com/test/_update/4gI4knQB7d5sAgV24YPy -d '{
"doc":  { "name" : "Ankit Singh Raj" }
}'

答案 6 :(得分:0)

<块引用>

按查询更新 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"
    }
  }
}   

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