Exists Query属于Term-level Query查询, 查询某字段值不为空的文档。脑图如下:

内容说明:
本文内容同微信公众号【凡登】,关注不迷路,欢迎加入一起共同学习。原文链接:Terms-level Query之Exists Query
目录
一、语法:
1、检索字段上存在值的文档
2、检索字段上不存在值的文档
二、Exists Query示例
0、数据准备
1、当字段值为空的演示示例:
2、当index:false情况下 演示示例
3、mapping设置ignore_above演示示例
4、mapping设置ignore_malformed演示示例
三、总结:
官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.13/query-dsl-exists-query.html
一、语法:
1、检索字段上存在值的文档
GET /_search{"query": {"exists": {"field": <field_name>}}}
参数说明:
-
field : 被检索的字段
通过bool改变Exists查询方式进行反向查询,即查询字段不存在值的文档。
2、检索字段上不存在值的文档
语法:
GET /_search{"query": {"bool": {"must_not": {"exists": {"field": <field_name>}}}}}
二、Exists Query示例
通过Exists Query可以查询字段值不为空的文档,那么在以下情况下
比如:
-
source中值可能为null, []
-
字段mapping参数index:false
-
字段值长度超过mapping中定义的ignore_above
-
当mapping中设置ignore_malformed,文档中字段值类型与mapping中定义的不一致
那么此时Exists Query会有什么样的表现?
0、数据准备
通过示例验证,演示数据准备如下:
DELETE exists_query_demo_index_001// 以下样例数据经过特殊设计,用于后续检索使用,// name字段用于验证空值// address 字段用于验证 index:false// content 字段用于验证ignore_above// age 字段用于验证ignore_malformed# 定义mappingPUT exists_query_demo_index_001{"mappings": {"properties": {"name":{"type":"keyword","fields": {"null_value":{"type":"keyword","null_value": "NULL" // 自定义空值},"text_value":{"type":"text"}}},"address":{"type":"text","fields": {"keyword_value_index_false":{"type":"keyword","index": false // index设置为false,即不被索引},"text_value_index_false":{"type":"text","index": false}}},"content":{"type":"keyword","ignore_above": 8 // 忽略字符长度大于8字段},"age":{"type":"integer","ignore_malformed": true // 忽略值异常字段值}}}}// 批量写入文档POST exists_query_demo_index_001/_bulk?refresh=true{"index":{"_id":1}}{"name":"Fan","address":"BJ_1","content":"helloFan","age":17}{"index":{"_id":2}}{"name":"Deng","address":"BJ_2","content":"helloDeng","age":"18岁"}{"index":{"_id":3}}{"name":"FanDeng","address":"BJ_3","content":"helloFanDeng","age":19}{"index":{"_id":4}}{"name":"","address":"BJ_4","content":"hello_","age":"20岁"}{"index":{"_id":5}}{"name":null,"address":"BJ_5","content":"hello_null","age":21}{"index":{"_id":6}}{"name":"NULL","address":"BJ_6","content":"hello_NULL","age":22}{"index":{"_id":7}}{"name":[],"address":"BJ_7","content":"hello_[]","age":"23岁"}{"index":{"_id":8}}{"name":[""],"address":"BJ_8","content":"hello_[empty_char]","age":24}{"index":{"_id":9}}{"name":[null],"address":"BJ_9","content":"hello_[null]","age":25}{"index":{"_id":10}}{"name":["NULL"],"address":"BJ_10","content":"hello_[NULL]","age":26}{"index":{"_id":11}}{"name":["","Fan"],"address":"BJ_11","content":"hello_[empty_char,Fan]","age":27}{"index":{"_id":12}}{"name":[null,"Fan"],"address":"BJ_12","content":"hello_[null,Fan]","age":28}{"index":{"_id":13}}{"name":["NULL","Fan"],"address":"BJ_13","content":"hello_[NULL,Fan]","age":29}//查询数据是否写入GET exists_query_demo_index_001/_search{"track_total_hits": true, // 显示检索数据的记录数"size": 0 // 不显示source}结果:{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 13, // 13条数据全部写入"relation" : "eq" //},"max_score" : null,"hits" : [ ]}}
1、当字段值为空的演示示例:
GET exists_query_demo_index_001/_search{"track_total_hits": true,"size": 20,"query": {"exists": {"field": "name"}}}结果显示:id为5,7,9的文档name不存在值即当字段值为null, 空数组[]或[null] 的时候,Exists Query检索不到相关文档以下query检查与上述查询结果相通GET exists_query_demo_index_001/_search{"track_total_hits": true,"size": 20,"query": {"exists": {"field": "name.text_value"}}}即类型为keyword以及text的字段,Exists Query查询结果相同我们通过反向查询看看字段name不存在值的文档有哪些GET exists_query_demo_index_001/_search{"track_total_hits": true,"query": {"bool": {"must_not": [{"exists": {"field": "name"}}]}}}结果:{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 0.0,"hits" : [{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "5","_score" : 0.0,"_source" : {"name" : null,"address" : "BJ_5","content" : "hello_null","age" : 21}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "7","_score" : 0.0,"_ignored" : ["age"],"_source" : {"name" : [ ],"address" : "BJ_7","content" : "hello_[]","age" : "23岁"}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "9","_score" : 0.0,"_source" : {"name" : [null],"address" : "BJ_9","content" : "hello_[null]","age" : 25}}]}}GET exists_query_demo_index_001/_search{"track_total_hits": true,"size": 20,"query": {"exists": {"field": "name.null_value"}}}结果显示:id为7的文档name不存在值即当字段值为 空数组[] 的时候,Exists Query检索不到相关文档字段name.null_value为自定义空值,当字段值出现空值的时候会填充自定义的默认值,故当检查到null 实际填充值为 NULL
小结:
即当字段值为null, 空数组[]或[null] 的时候,Exists Query检索不到相关文档,
如果自定义了空值,那么仅字段值空数组[]下,Exists Query检索不到相关文档
2、当index:false情况下 演示示例
GET exists_query_demo_index_001/_search{"size": 20,"query": {"exists": {"field": "address"}}}结果:所有文档的address字段均存在值,GET exists_query_demo_index_001/_search{"size": 20,"query": {"exists": {"field": "address.keyword_index_false"}}}结果:所有文档的address字段均不存在值,GET exists_query_demo_index_001/_search{"size": 20,"query": {"exists": {"field": "address.text_index_false"}}}结果:所有文档的address字段均不存在值,
小结:当index:false时,所有文档的address字段均不存在值,Exists Query检索不到相关文档
3、mapping设置ignore_above演示示例
GET exists_query_demo_index_001/_search{"size": 20,"query": {"exists": {"field": "content"}}}结果:{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"name" : "Fan","address" : "BJ_1","content" : "helloFan","age" : 17}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "4","_score" : 1.0,"_ignored" : ["age"],"_source" : {"name" : "","address" : "BJ_4","content" : "hello_","age" : "20岁"}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "7","_score" : 1.0,"_ignored" : ["age"],"_source" : {"name" : [ ],"address" : "BJ_7","content" : "hello_[]","age" : "23岁"}}]}}
小结:
当字段值超过ignore_above配置的长度时,Exists Query检索不到相关文档
4、mapping设置ignore_malformed演示示例
GET exists_query_demo_index_001/_search{"size": 20,"query": {"exists": {"field": "age"}}}通过反向查询看看有哪些age字段不存在值的文档GET exists_query_demo_index_001/_search{"track_total_hits": true,"query": {"bool": {"must_not": [{"exists": {"field": "age"}}]}}}结果:{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 0.0,"hits" : [{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "2","_score" : 0.0,"_ignored" : ["age"],"_source" : {"name" : "Deng","address" : "BJ_2","content" : "helloDeng","age" : "18岁"}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "4","_score" : 0.0,"_ignored" : ["age"],"_source" : {"name" : "","address" : "BJ_4","content" : "hello_","age" : "20岁"}},{"_index" : "exists_query_demo_index_001","_type" : "_doc","_id" : "7","_score" : 0.0,"_ignored" : ["age"],"_source" : {"name" : [ ],"address" : "BJ_7","content" : "hello_[]","age" : "23岁"}}]}}
小结:
当ignore_malformed配置时,字段值类型与mapping中字段类型不一致或一些不符合要求的字段值,Exists Query检索不到相关文档
三、总结:
针对Exists Query检索,以下4种情况会出现Exists Query检索不到相关文档
-
1、当检索字段值为null, 空数组[], [null], Exists Query检索不到相关文档。存在自定义空值则除外
-
2、当index:false时,所有文档的address字段均不存在值,Exists Query检索不到相关文档
-
3、当字段值超过ignore_above配置的长度时,Exists Query检索不到相关文档
-
4、当ignore_malformed配置时,字段值类型与mapping中字段类型不一致或一些不符合要求的字段值,Exists Query检索不到相关文档













