前言
布尔查询是最常见的组合查询,根据子查询的规则,只有当文档满足所有子查询条件时,Elastic Search 引擎才会将结果返回。布尔查询支持的子查询条件共4种:
- must(and)
- should(or)
- must_not(not)
- filter
准备数据
PUT zhifou/doc/1 { "name":"顾老二", "age":30, "from":"gu", "desc":"皮肤黑、武器长、性格直", "tags":["黑","长","直"] } PUT zhifou/doc/2 { "name":"大娘子", "age":18, "from":"sheng", "desc":"貌美肤白、娇憨可爱", "tags":["白","富","美"] } PUT zhifou/doc/3 { "name":"龙套偏房", "age":22, "from":"gu", "desc":"mmp,没怎么看清,不知道怎么形容", "tags":["造数据","真","难"] } PUT zhifou/doc/4 { "name":"石头", "age":29, "from":"gu", "desc":"粗中有细、狐假虎威", "tags":["粗","大","猛"] } PUT zhifou/doc/5 { "name":"魏行者", "age":25, "from":"广云台", "desc":"后悔没能嫁给顾老二~", "tags":["闭月","羞花"] }
must
现在我们使用布尔查询所有from
属性为gu
的数据
GET zhifou/doc/_search { "query":{ "bool": { "must": [ { "match": { "from": "gu" } } ] } } }
结果如下:
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 0.82876295, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.82876295, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "3", "_score" : 0.82876295, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看清,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.82876295, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细、狐假虎威", "tags" : [ "粗", "大", "猛" ] } } ] } }
在上面的例子中,通过bool
属性字段内使用must来作为查询条件,这里需要注意的是must
字段对应的是个列表,也就是说可以有多个并列的查询条件,一个文档满足各个子条件后才最终返回。
栗子:如果想要查询from为gu,并且年龄为30的数据应该怎样操作?
GET zhifou/doc/_search { "query":{ "bool": { "must": [ { "match": { "from": "gu" } }, { "match": { "age": 30 } } ] } } }
结果返回:
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.828763, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 1.828763, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
should
那么,如果查询只要是from
为gu
或者tags
为闭月
的数据呢?
GET zhifou/doc/_search { "query":{ "bool": { "should": [ { "match": { "from": "gu" } }, { "match": { "tags": "闭月" } } ] } } }
结果返回:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 4, "relation" : "eq" }, "max_score" : 1.9854019, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "5", "_score" : 1.9854019, "_source" : { "name" : "魏行者", "age" : 25, "from" : "广云台", "desc" : "后悔没能嫁给顾老二~", "tags" : [ "闭月", "羞花" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.82876295, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "3", "_score" : 0.82876295, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看清,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.82876295, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细、狐假虎威", "tags" : [ "粗", "大", "猛" ] } } ] } }
以上栗子中,只要符合其中一个条件就可返回。
must_not
那么,如果我想要查询from
既不是gu
并且tags
也不是可爱
,还有age
不是18
的数据
GET zhifou/doc/_search { "query":{ "bool": { "must_not": [ { "match": { "from": "gu" } }, { "match": { "tags": "可爱" } }, { "match": { "age": 18 } } ] } } }
结果返回:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.0, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "5", "_score" : 0.0, "_source" : { "name" : "魏行者", "age" : 25, "from" : "广云台", "desc" : "后悔没能嫁给顾老二~", "tags" : [ "闭月", "羞花" ] } } ] } }
以上例子中,只有魏行者满足要求,因为魏行者既不是顾家的人
,标签里也没有可爱的那一项,年龄也不等于18~
filter
那么,要查询from
为gu
,age
大于25
的数据该怎么查?
GET zhifou/doc/_search { "query":{ "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gt":25 } } } } } }
结果返回:
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 2, "relation" : "eq" }, "max_score" : 0.82876295, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.82876295, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.82876295, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细、狐假虎威", "tags" : [ "粗", "大", "猛" ] } } ] } }
小结:
- must:与关系,相当于and
- Should:或关系,相当于or
- must_not:非关系,相当于not
- filter:过滤条件
- range:条件筛选范围
- gt(getter than):大于
- gte(geeter than equals):大于等于
- lt(less than):小于
- lte(less than equals):小于等于
来源:https://www.cnblogs.com/shine-rainbow/p/12207773.html