• 速看,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

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

  • 相关阅读:
    【C++】多态
    【华为OD机试真题 JAVA】靠谱的车
    【MySQL】MySQL的自然连接和USING连接详细总结
    操作系统 线程死锁
    10.力扣c++刷题-->两数之和
    Linux 基础-查看和设置环境变量
    PBX与VoIP:它们之间有什么区别?
    Altera(Intel)时序约束文件SDC
    小白也能搞通UDP通信(88E1111 RGMII 接口)
    前馈神经网络
  • 原文地址:https://www.cnblogs.com/fkaka/p/16080333.html