这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战
本Elasticsearch相关文章的版本为:7.4.2
exists查询:返回所查询的字段包含具有索引值的文档。
不存在索引值的情况
字段不存在索引值的情况有以下几种:
- 字段的源json值为null或[];
- 字段的值的长度超过了ignore_above所设置的值;
- 字段的值有问题,但是设置了ignore_malformed, 这个字段的值会被丢弃或不进行索引。
测试数据:
PUT /exists_test
{
"mappings": {
"properties": {
"name": {
"type": "keyword",
"index": true,
"ignore_above": 3
},
"age": {
"type": "long",
"index": true,
"ignore_malformed": true
}
}
}
}
POST /exists_test/_doc/1
{
"name": "beijing",
"age": "xx"
}
POST /exists_test/_doc/2
{
"name": "",
"age": 5
}
POST /exists_test/_doc/3
{
"name": [],
"age": 5
}
POST /exists_test/_doc/4
{
"name": null,
"age": 5
}
测试null和ignore_above
校验当字段的源json值为null或[]时以及字段的值的长度超过了ignore_above所设置的值,那么exists查询这个字段时不会返回文档。
GET /exists_test/_search
{
"query":{
"exists": {
"field": "name"
}
}
}
返回结果: 因为doc1的name的值长度大于3,所以不会进行倒排索引,所以exists查询没有命中;doc3和doc4的值为null和[], 所以exists查询这个字段时也不会返回文档。
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "exists_test",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "",
"age" : 5
}
}
]
}
}
测试数据类型错误时
校验字段的值有问题,但是设置了ignore_malformed, 这个字段的值会不进行索引。
GET /exists_test/_search
{
"query":{
"exists": {
"field": "age"
}
}
}
返回结果: 因为文档1的age的值为字符串"xx" , 但是age的数据类型在mapping中是long整数,所以数据类型不对,但是设置了ignore_malformed, 这个字段的值不进行索引。所以exists查询就不会返回doc1。
{
"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_test",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "",
"age" : 5
}
},
{
"_index" : "exists_test",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"name" : [ ],
"age" : 5
}
},
{
"_index" : "exists_test",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : null,
"age" : 5
}
}
]
}
}
注意: 属于有值的几种特殊情况:
- 字符串空串
""或"-"; - 数组包含null同时包含另外的有值的数据:
[null, "test"]; - 在mapping里定义的自定义的null-value
获取缺失索引值的文档的方法
当要获取缺失索引值的文档时,可以结合使用must_not的boolean查询和exists查询实现。
GET /exists_test/_search
{
"query": {
"bool": {
"must_not": [
{"exists": {"field":"age"}}
]
}
}
}
查询age字段不存在索引值的文档:
因为文档2,3,4的age的值为5,所以它们是存在索引值的。但是文档1的age的值是字符串"xx",不是一个合法的long整数,不存在索引值。所以下面的查询只返回了文档1。
返回的结果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "exists_test",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_ignored" : [
"age"
],
"_source" : {
"name" : "beijing",
"age" : "xx"
}
}
]
}
}