乐趣区

关于elasticsearch:速看ElasticSearch如何处理空值

大家好,我是咔咔 不期速成,日拱一卒

在 MySQL 中,非常不倡议大家给表的默认值设置为 Null,这个前期咔咔也会独自出一期文章来阐明这个事件。

但你进入一家新公司之前的业务中存在大量的字段默认值为 Null,把这些值导入 ElasticSearch 中还是须要解决,接下来就看看 ElasticSearch 如何应答空值。

一、ElasticSearch 如何解决 Null 值的

先看一个案例,当值为 null 时会产生什么

POST /kaka/_bulk
{"index": { "_id": "1"}}
{"tags" : ["search"]}  
{"index": { "_id": "2"}}
{"tags" : ["search", "open_source"] }  
{"index": { "_id": "3"}}
{"tags" : null}  
{"index": { "_id": "4"}}
{"tags" :"null"}

在这个案例中能够发现,第 3、4 都存在一个 null 值,不同的是一个为字符串 null

post /kaka/_search
{
  "query":{
    "term": {"tags": null}
  },
  "profile":"true"
}

当你执行下面这搜寻时会呈现上面这个谬误

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "field name is null or empty"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "field name is null or empty"
  },
  "status": 400
}

而后咔咔就跑到 ElasticSearch 文档找了一下起因,是因为在 ElasticSearch 中空值不能被索引或搜寻,当字段值为 null 时、空数组、null 值数组时,会将其视为该字段没有值

若你执行的语句为如下,则会返回最初一条数据

post /kaka/_search
{
  "query":{
    "term": {"tags": "null"}
  },
  "profile":"true"
}

二、应用 exists 解决 ElasticSearch 中 Null 值搜寻问题

同样在文档中咔咔也找到了答案,案例如下

post /kaka/_search
{
  "query":{
    "constant_score": {
      "filter": {
        "missing": {"field": "tags"}
      }
    }
  }
}

执行后果返回 no [query] registered for [missing],这就让人有点百思不得其解,再通过啃文档后发现这个接口在 ElasticSearch7.1 曾经被勾销了,依据文档的意思是exists 能够同时满足存在和不存在两种状况

先看应用 exists 如何查问不为 null

post /kaka/_search
{
  "query":{
    "constant_score":{
      "filter":{
        "exists":{"field":"tags"}
      }
    }
  }
}

再看应用 exists 查问为 null 的

post /kaka/_search
{
  "query":{
    "bool":{
      "must_not":{
        "exists":{"field":"tags"}
      }
    }
  }
}

三、应用 null_value 替换显示的空值

删除上边定义的索引delete kaka,而后自定义 mapping,给 tags 设置"null_value":"null",用指定的值替换显示的空值,”null” 能够自定义为任意值

应用了 null_value 这样做的益处就是空字段也能够被索引,同时也不会在查问时报 field name is null or empty 的谬误

put kaka
{
  "mappings":{
    "properties":{
      "tags" :{
        "type":"keyword",
        "null_value":"null"
      }
    }
  }
}

再插入上边的数据

POST /kaka/_bulk
{"index": { "_id": "1"}}
{"tags" : ["search"]}  
{"index": { "_id": "2"}}
{"tags" : ["search", "open_source"] }  
{"index": { "_id": "3"}}
{"tags" : null}  
{"index": { "_id": "4"}}
{"tags" :"null"}

再次执行查问为 null 的数据,就会呈现第 3、4 条数据

post /kaka/_search
{
  "query":{
    "term": {"tags": "null"}
  },
  "profile":"true"
}

四、应用 null_value 留神点

null_value 必须和定义的数据类型匹配,例如 long 类型的不能定义字符串类型的 value_null 值

看一下 long 类型设置了字符串类型 value_null 会呈现什么谬误

# 谬误演示,long 类型应用了字符串类型的 null_value 值
put kaka
{
  "mappings":{
    "properties":{
      "tags" :{
        "type":"long",
        "null_value":"null"
      }
    }
  }
}

返回谬误如下

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "Failed to parse mapping [_doc]: For input string: \"null\""
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "Failed to parse mapping [_doc]: For input string: \"null\"","caused_by": {"type":"number_format_exception","reason":"For input string: \"null\""}
  },
  "status": 400
}

留神了数据类型外,你还须要晓得 value_null 不是任何类型都能够应用的,以下列举的类型都可应用 null_value

  • Array
  • Boolean
  • Date
  • geo_point
  • ip
  • keyword
  • Numeric
  • point

保持学习、保持写作、保持分享是咔咔从业以来所秉持的信念。愿文章在偌大的互联网上能给你带来一点帮忙,我是咔咔,下期见。

退出移动版