一、exists查詢簡介
elastic search提供了exists查詢,用以返回欄位存在值的記錄,預設情況下只有欄位的值為null或者[]的時候,elasticsearch才會認為欄位不存在;
exists查詢的形式如下,其中field用於指定要查詢的欄位名字;
{
"query": {
"exists": {
"field": "user"
}
}
}
二、測試資料準備
我們儘量模擬document中欄位可能出現的各種形式,以便可以全面的測試以下exists查詢;
PUT exists_test/_doc/1/
{
"name":"sam",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/2/
{
"name":"",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/3/
{
"name":null,
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/4/
{
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/5/
{
"name":"sam",
"age":null,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/6/
{
"name":"sam",
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/7/
{
"name":"sam",
"age":30,
"man": null,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/8/
{
"name":"sam",
"age":30,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/9/
{
"name":"sam",
"age":30,
"man": true,
"child":["", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/10/
{
"name":"sam",
"age":30,
"man": true,
"child":["", ""],
"address":{"country":"US"}
}
PUT exists_test/_doc/11/
{
"name":"sam",
"age":30,
"man": true,
"child":[null, "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/12/
{
"name":"sam",
"age":30,
"man": true,
"child":[null, null],
"address":{"country":"US"}
}
PUT exists_test/_doc/13/
{
"name":"sam",
"age":30,
"man": true,
"child":[],
"address":{"country":"US"}
}
PUT exists_test/_doc/14/
{
"name":"sam",
"age":30,
"man": true,
"child":null,
"address":{"country":"US"}
}
PUT exists_test/_doc/15/
{
"name":"sam",
"age":30,
"man": true,
"address":{"country":"US"}
}
PUT exists_test/_doc/16/
{
"name":"sam",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{}
}
PUT exists_test/_doc/17/
{
"name":"sam",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":null
}
PUT exists_test/_doc/18/
{
"name":"sam",
"age":30,
"man": true,
"child":["jhon", "lily"]
}
PUT exists_test/_doc/19/
{
"name":"sam",
"age":0,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/20/
{
"name":"-",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
PUT exists_test/_doc/21/
{
"name":";",
"age":30,
"man": true,
"child":["jhon", "lily"],
"address":{"country":"US"}
}
三、exists查詢測試
對於字串型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;欄位值為空則計算為欄位存在;
POST exists_test/_doc/_search/
{
"query":{
"bool":{
"must_not":{
"exists":{
"field":"name"
}
}
}
}
}
{
"took":3,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":2,
"max_score":1,
"hits":[
{
"_index":"exists_test",
"_type":"_doc",
"_id":"4",
"_score":1,
"_source":{
"age":30,
"man":true,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"3",
"_score":1,
"_source":{
"name":null,
"age":30,
"man":true,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
}
]
}
}
對於數位型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;
POST exists_test/_doc/_search/
{
"query":{
"bool":{
"must_not":{
"exists":{
"field":"age"
}
}
}
}
}
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":2,
"max_score":1,
"hits":[
{
"_index":"exists_test",
"_type":"_doc",
"_id":"5",
"_score":1,
"_source":{
"name":"sam",
"age":null,
"man":true,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"6",
"_score":1,
"_source":{
"name":"sam",
"man":true,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
}
]
}
}
對於布林型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;
POST exists_test/_doc/_search/
{
"query":{
"bool":{
"must_not":{
"exists":{
"field":"man"
}
}
}
}
}
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":2,
"max_score":1,
"hits":[
{
"_index":"exists_test",
"_type":"_doc",
"_id":"8",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"7",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":null,
"child":[
"jhon",
"lily"
],
"address":{
"country":"US"
}
}
}
]
}
}
對於陣列型別欄位,只要欄位沒有出現、欄位值為null、欄位值為空陣列、欄位值陣列的所有元素都為null,則該欄位不存在;
POST exists_test/_doc/_search/
{
"query":{
"bool":{
"must_not":{
"exists":{
"field":"child"
}
}
}
}
}
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":1,
"hits":[
{
"_index":"exists_test",
"_type":"_doc",
"_id":"14",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":null,
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"12",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":[
null,
null
],
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"15",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"address":{
"country":"US"
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"13",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":[
],
"address":{
"country":"US"
}
}
}
]
}
}
對於物件欄位,只要欄位沒有出現、欄位值是空物件、欄位值為null,則該欄位不存在;
POST exists_test/_doc/_search/
{
"query":{
"bool":{
"must_not":{
"exists":{
"field":"address"
}
}
}
}
}
{
"took":40,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":3,
"max_score":1,
"hits":[
{
"_index":"exists_test",
"_type":"_doc",
"_id":"16",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":[
"jhon",
"lily"
],
"address":{
}
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"18",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":[
"jhon",
"lily"
]
}
},
{
"_index":"exists_test",
"_type":"_doc",
"_id":"17",
"_score":1,
"_source":{
"name":"sam",
"age":30,
"man":true,
"child":[
"jhon",
"lily"
],
"address":null
}
}
]
}
}
四、測試總結
elasticsearch對於各種型別欄位判斷欄位是否存在的判斷條件如下
1.對於字串型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;欄位值為空則計算為欄位存在;
2.對於數位型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;
3.對於布林型別欄位,當欄位沒有出現、欄位值為null的情況下,則該欄位不存在;
4.對於陣列型別欄位,只要欄位沒有出現、欄位值為null、欄位值為空陣列、欄位值陣列的所有元素都為null,則該欄位不存在;
5.對於物件欄位,只要欄位沒有出現、欄位值是空物件、欄位值為null,則該欄位不存在;