elasticsearch之布尔查询
前言
布尔查询是最常用的组合查询,根据子查询的规则,只有当文档满足所有子查询条件时,elasticsearch引擎才将结果返回。布尔查询支持的子查询条件共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":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags":["闭月","羞花"] }
must(and)
用布尔查询所有from属性为gu的数据:
GET zhifou/doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ] } } }
上例中,我们通过在bool属性(字段)内使用must来作为查询条件,那么条件是什么呢?条件同样被match包围,就是from为gu的所有数据。这里需要注意的是must字段对应的是个列表,也就是说可以有多个并列的查询条件,一个文档满足各个子条件后才最终返回。
结果
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 0.6931472, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "3", "_score" : 0.2876821, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
查询from为gu,并且age为30的数据
GET zhifou/doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } }, { "match": { "age": 30 } } ] } } }
注意:现在你可能慢慢发现一个现象,所有属性值为列表的,都可以实现多个条件并列存在
should(or)
查询只要是from为gu或者tags为闭月
GET zhifou/doc/_search { "query": { "bool": { "should": [ { "match": { "from": "gu" } }, { "match": { "tags": "闭月" } } ] } } }
或关系的不能用must的了,而是要用should,只要符合其中一个条件就返回。
结果
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 4, "max_score" : 0.6931472, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "5", "_score" : 0.5753642, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "3", "_score" : 0.2876821, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
返回了所有符合条件的结果
must_not(not)
查询from既不是gu并且tags也不是可爱,还有age不是18的数据
GET zhifou/doc/_search { "query": { "bool": { "must_not": [ { "match": { "from": "gu" } }, { "match": { "tags": "可爱" } }, { "match": { "age": 18 } } ] } } }
must和should都不能使用,而是使用must_not,又在内增加了一个age为18的条件。
结果
{ "took" : 9, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "5", "_score" : 1.0, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] } } ] } }
只有魏行首这一条数据,因为只有魏行首既不是顾家的人,标签没有可爱那一项,年龄也不等于18!这里有点需要补充,条件中age对应的18你写成整形还是字符串都没啥……
filter
lt小于 lte小于等于
gt大于 gte大于等于
使用lte
和gte
来限定范围
查询from为gu,age大于25的数据
GET zhifou/doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gt": 25 } } } } } }
filter条件过滤查询,过滤条件的范围用range表示,gt表示大于,大于多少呢?是25。
结果
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.6931472, "hits" : [ { "_index" : "zhifou", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "zhifou", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
age
大于25
的条件都已经筛选出来了。
查询from
是gu
,age
大于等于30
GET zhifou/doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gte": 30 } } } } } }
大于等于用gte
表示。
查询age
小于25
GET zhifou/doc/_search { "query": { "bool": { "filter": { "range": { "age": { "lt": 25 } } } } } }
小于用lt
表示
查询一个age
小于等于18
GET zhifou/doc/_search { "query": { "bool": { "filter": { "range": { "age": { "lte": 18 } } } } } }
小于等于用lte
表示
查询from
是gu
,age
在25~30
之间
GET zhifou/doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gte": 25, "lte": 30 } } } } } }
参考博客
https://www.cnblogs.com/Neeo/articles/10578625.html#should