在 Mapping 里面,将 dynamic 参数设置成 strict 可以拒绝索引包含未知字段的文档。 此条 Tips 由 medcl 贡献。

elasticsearch如何为类型添加字段并赋初值

匿名 | 发布于2017年03月18日 | 阅读数:32909

elasticsearch如何为指定索引中类型添加字段并赋初值,就像数据库中添加字段为老的数据赋初始值一样。
已邀请:

kennywu76 - Wood

赞同来自: 方磊 liuyt123 josancpp

用update_by_query结合script可以办到,例如:
POST my_index/_update_by_query
{
"script": {
"lang": "painless",
"inline": "if (ctx._source.status_code == null) {ctx._source.status_code= '02'}"
}
}

kennywu76 - Wood

赞同来自: liuyt123 ymsun

在ES里为已有索引增加一个新字段以后,老的数据并不会自动就拥有了这个新字段,也就不可能给他一个所谓的默认值。ES里的数据都是文档型的,修改一个文档只能是对原文档做更新,也就是只能借助于重新索引的手段。
 
NULL在ES里的含义和RDBMS非常不同。 
 
NULL的意思是索引的时候,某个字段没有被赋值,例如文档有"city","title"和"status_code"三个字段。
 
索引的时候漏掉status_code字段:
PUT my_index/my_type/1
{
"city": "NJ",
"title": "Document 1"
}
或者显式给status_code一个空值:
PUT my_index/my_type/2
{
  "city": "BJ",
  "title": "Document 2",
   "status_code": null
}

示例里的两条文档的status_code这个字段都是被忽略,不做索引的,因此也就无法做所谓的空值搜索。
 
因此,为了支持做“status_code = NULL”这样的搜索,就可以配置一个可选的null_value选项:
"properties": {
"status_code": {
"type": "keyword",
"null_value": "NULL"
}
}

null_value的值可以任意指定,但是必须和status_code的字段类型一致。 比如配置的keyword类型,null_value就必须是字符型。 如果是long类型,null_value就必须是个数字。 类型不一致会报错。
 
 

kennywu76 - Wood

赞同来自: josancpp

自动添加的字段是multi-filed,分别是text和keyword,不是最优的。  status这个字段看起来就是存放状态吗,只用keyword足够了。 更好的做法是先update mapping,添加status这个字段为keyword,之后再用update_by_query更新旧数据的值。

medcl - 今晚打老虎。

赞同来自:

es支持对null值设置默认值,文档:https://www.elastic.co/guide/e ... .html
 
匿名用户

匿名用户

赞同来自:

不能赋其它值吗,我请求报错:
D:\curl\bin>curl -XPUT "http://localhost:9200/vewiki_i ... ot%3B -d "{\"vewiki\":{\"properties\":{\"status\":{\"type\":\"text\",\"null_value\":\"02\"}}}}"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "mapper_parsing_exception",
        "reason" : "Mapping definition for [status] has unsupported parameters:  [null_value : 02]"
      }
    ],
    "type" : "mapper_parsing_exception",
    "reason" : "Mapping definition for [status] has unsupported parameters:  [null_value : 02]"
  },
  "status" : 400
}

hhh_mmm

赞同来自:

那能否有办法,老的数据对这个新字段做一次性默认值赋值修改。

hhh_mmm

赞同来自:

有什么办法可以做到吗,我数据库要添加一个业务字段,并且从业务上为了兼容老的数据,必须为老数据该字段添加一个默认值。

hhh_mmm

赞同来自:

谢谢,可以了,我执行
POST my_index/_update_by_query
{
    "script":{
        "lang":"painless",
        "inline":"if (ctx._source.status == null) {ctx._source.status= '02'}"
    }
}
 
它自动为我的索引的mapping创建了status这个字段,并且赋值成功。
字段描述如下:
 "status" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },

要回复问题请先登录注册