1. 程式人生 > 其它 >速看,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

堅持學習、堅持寫作、堅持分享是咔咔從業以來所秉持的信念。願文章在偌大的網際網路上能給你帶來一點幫助,我是咔咔,下期見。