elasticsearch之exists查詢

無風聽海發表於2023-01-12

一、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,則該欄位不存在;

相關文章