08-DSL查询语法-BooleanQuery
1.复合查询 Boolean Query
布尔查询是一个或多个查询子句的组合。子查询的组合方式有:
(1)must
:必须匹配每个子查询,类似“与”
(2)should
:选择性匹配子查询,类似“或”
(3)must_not
:必须不匹配,不参与算分,类似“非”
(4)filter
:必须匹配,不参与算分
解释:
ES在做搜索的时候,不仅仅是判断文档是否匹配,他还要看你这个文档跟关键字之间的相关度,给你打分,分值越高排名越靠前。这个打分有个非常复杂的bm25函数,因此每做一次算分,其实都会消耗一些资源。如果子查询比较多,每一个都参与算分,查询性能就会收到影响。而如果在使用的时候用的是must_not和filter查询,他们是不参与算分的,他们只会返回满足或者不满足的结果,因此这种查询不做算分性能就很好。又因为查询的结果就是简单的是或否,我们的ES还会把这种过滤性的查询filter这种,把他放到缓存里面去,进来再次查询的时候,会进一步的去提升性能。
因此,虽然Boolean查询里面有四种组合关系,但是除了跟算分相关的,一般就是关键字,用户输入的那个,除了那个以外,他应该放到must或shoud里面以外,剩下的过滤条件都应该放到must或者filter里面,尽可能减少算分,提高查询效率。
什么情况下会用到这种复合查询呢?
比如有一个页面,去搜索一个酒店信息,首先在输入框里面输入酒店信息,然后你还可以在下面选择过滤条件,比如要求价格在100-300之间,同时要求地址在上海,这个时候你的要求就是“满足输入的名字,并且城市在上海,并且价格范围在100-300之间”这种关系组合了。但是这个时候,关键字的搜索可以放到must里面,因为他要参与算分,但是下面的这些过滤条件,最好放到must_not和filter里面,因为放到这里面不参与算分,性能更好。
2.案例:利用bool查询实现功能
需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。
GET /hotel/_search