must使用
文档必须匹配must查询条件,我们这里设置要查询的内容为【年龄在10-19岁之间 且 性别为男 且 姓名开头为森】的员工,查询语句为:
{"query":{ "bool": { "must": [ {"term": {"sex": "男"}}, {"range": {"age": { "gte" : 18, "lt" : 29}}}, {"prefix": {"name": "森"}} ] } } }
返回结果为:
{ "took": 54, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 2.6931472, "hits": [ { "_index": "tml-userinfo", "_type": "_doc", "_id": "1", "_score": 2.6931472, "_source": { "age": 18, "sex": "男", "name": "森小辰" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "2", "_score": 2.575364, "_source": { "age": 28, "sex": "男", "name": "森小林" } } ] } }
should使用
文档应该匹配should子句查询的一个或多个,这里我们来查询【年龄在10-19岁之间 或 性别为男 或 姓名开头为森】,查询语句为:
{"query":{ "bool": { "should": [ {"term": {"sex": "男"}}, {"range": {"age": { "gte" : 18, "lt" : 29}}}, {"prefix": {"name": "森"}} ] } } }
返回结果为:
{ "took": 48, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 14, "relation": "eq" }, "max_score": 2.597837, "hits": [ { "_index": "tml-userinfo", "_type": "_doc", "_id": "1", "_score": 2.597837, "_source": { "age": 18, "sex": "男", "name": "森小辰" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "2", "_score": 2.4418328, "_source": { "age": 28, "sex": "男", "name": "森小林" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "9", "_score": 2.0, "_source": { "age": 18, "sex": "女", "name": "森小玲" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "11", "_score": 2.0, "_source": { "age": 28, "sex": "女", "name": "森小捷" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "5", "_score": 1.9808291, "_source": { "age": 28, "sex": "男", "name": "李小林" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "6", "_score": 1.597837, "_source": { "age": 28, "sex": "男", "name": "李小林" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "3", "_score": 1.4418328, "_source": { "age": 8, "sex": "男", "name": "森小贤" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "12", "_score": 1.4418328, "_source": { "age": 18, "sex": "男", "name": "李小辰" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "13", "_score": 1.0, "_source": { "age": 18, "sex": "女", "name": "李小男" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "15", "_score": 1.0, "_source": { "age": 18, "sex": "woman", "name": "赵小男" } } ] } }
可以看到只有一条数据没有返回,因为不符合shoud的任意一个条件
must_not使用
文档不能匹配该查询条件,这里我们来查询【年龄不在10-19岁之间 且 性别不为男 且 姓名开头不为森】,查询语句为:
{"query":{ "bool": { "must_not": [ {"term": {"sex": "男"}}, {"range": {"age": { "gte" : 18, "lt" : 29}}}, {"prefix": {"name": "森"}} ] } } }
我们可以看到,返回结果刚好为shoud的相反条件:
{ "took": 17, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.0, "hits": [ { "_index": "tml-userinfo", "_type": "_doc", "_id": "7", "_score": 0.0, "_source": { "age": 8, "sex": "女", "name": "李小美" } } ] } }
filter使用
过滤器,文档必须匹配该过滤条件,跟must子句的唯一区别是,filter不影响查询的score,我们这里设置要查询的内容为【年龄在10-19岁之间 且 性别为男 且 姓名开头为森】的员工,查询语句为:
{"query":{ "bool": { "filter": [ {"term": {"sex": "男"}}, {"range": {"age": { "gte" : 18, "lt" : 29}}}, {"prefix": {"name": "森"}} ] } } }
返回结果为:
{ "took": 7, // 请求花了多少时间 "timed_out": false, //有没有超时 "_shards": { //执行请求时查询的分片信息 "total": 3, //查询的分片数量 "successful": 3, // 成功返回结果的分片数量 "skipped": 0, // 跳过的分片数量 "failed": 0 // 失败的分片数量 }, "hits": { "total": { "value": 2, //查询返回的文档总数 "relation": "eq" }, "max_score": 0.0, //计算所得的最高分 "hits": [ { "_index": "tml-userinfo", //索引 "_type": "_doc", //类型 "_id": "2", //标识符 "_score": 0.0, //得分 "_source": { //发送到索引的Json对象 "age": 28, "sex": "男", "name": "森小林" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "1", "_score": 0.0, "_source": { "age": 18, "sex": "男", "name": "森小辰" } } ] } }
可以看到,返回的score为0,但是took为7,比must的54快了近8倍多。
多子句复合查询
我们在真实使用复合查询的时候肯定不仅仅要查单种条件的复合关系,还需要查多种关联条件,这里我们查一个【年龄在10-19岁之间 且 性别为男 且 姓名开头为森】或【姓名以男字结尾】但【年龄不能是28岁的】,需要注意:Boolean在同时有must和should的时候,should就被过滤掉了,因为should表示有也可以没有也可以,所以我们常把must放到should字句里,确保should的子句能执行
{ "query": { "bool": { "should": [ { "wildcard": { "name": "*男" } }, { "bool": { "must": [ { "term": { "sex": "男" } }, { "range": { "age": { "gte": 18, "lt": 29 } } }, { "prefix": { "name": "森" } } ] } } ], "must_not": [ { "term": { "age": 28 } } ] } } }
返回结果如下:
{ "took": 14, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": 2.6931472, "hits": [ { "_index": "tml-userinfo", "_type": "_doc", "_id": "1", "_score": 2.6931472, "_source": { "age": 18, "sex": "男", "name": "森小辰" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "13", "_score": 1.0, "_source": { "age": 18, "sex": "女", "name": "李小男" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "14", "_score": 1.0, "_source": { "age": 18, "sex": "", "name": "李小男" } }, { "_index": "tml-userinfo", "_type": "_doc", "_id": "15", "_score": 1.0, "_source": { "age": 18, "sex": "woman", "name": "赵小男" } } ] } }
整个过程是先做should操作(must作为其子句),操作完后再用must_not把当前结果集中的数据干掉。