美文网首页
速看,ElasticSearch如何处理空值

速看,ElasticSearch如何处理空值

作者: 原来是咔咔吖 | 来源:发表于2022-03-31 09:42 被阅读0次

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

在MySQL中,十分不建议大家给表的默认值设置为Null,这个后期咔咔也会单独出一期文章来说明这个事情。

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

3a8e2fbd8e234773a38eb7fc36386eb3.png

一、ElasticSearch如何处理Null值的

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">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"} </pre>

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "term": { "tags": null } }, "profile":"true" } </pre>

当你执行上面这搜索时会出现下面这个错误

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">{ "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 } </pre>

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

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "term": { "tags": "null" } }, "profile":"true" } </pre>

二、使用exists解决ElasticSearch中Null值搜索问题

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "constant_score": { "filter": { "missing": { "field": "tags" } } } } } </pre>

执行结果返回no [query] registered for [missing],这就让人有点百思不得其解,再通过啃文档后发现这个接口在ElasticSearch7.1已经被取消了,根据文档的意思是exists可以同时满足存在和不存在两种情况

先看使用exists如何查询不为null

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "constant_score":{ "filter":{ "exists":{ "field":"tags" } } } } } </pre>

再看使用exists查询为null的

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "bool":{ "must_not":{ "exists":{ "field":"tags" } } } } } </pre>

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

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

使用了null_value这样做的好处就是空字段也可以被索引,同时也不会在查询时报field name is null or empty的错误

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">put kaka { "mappings":{ "properties":{ "tags" :{ "type":"keyword", "null_value":"null" } } } } </pre>

再插入上边的数据

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">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"} </pre>

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">post /kaka/_search { "query":{ "term": { "tags": "null" } }, "profile":"true" } </pre>

四、使用null_value注意点

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

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

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"># 错误演示,long类型使用了字符串类型的null_value值 put kaka { "mappings":{ "properties":{ "tags" :{ "type":"long", "null_value":"null" } } } } </pre>

返回错误如下

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">{ "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 } </pre>

注意了数据类型外,你还需要知道value_null不是任何类型都可以使用的,以下列举的类型都可使用null_value

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

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

相关文章

网友评论

      本文标题:速看,ElasticSearch如何处理空值

      本文链接:https://www.haomeiwen.com/subject/dligjrtx.html