Elasticsearch(下面简称ES)中的bool查询在业务中使用也是比较多的。在一些非实时的分页查询,导出的场景,咱们常常使用bool查询组合各类查询条件。缓存
Bool查询包括四种子句,性能
我这里只介绍下must和filter两种子句,由于是咱们今天要讲的重点。其它的能够自行查询官方文档。优化
从上面的描述来看,你应该已经知道,若是只看查询的结果,must和filter是同样的。区别是场景不同。若是结果须要算分就使用must,不然能够考虑使用filter。ui
光说比较抽象,看个例子,下面两个语句,查询的结果是同样的。spa
使用filter过滤时间范围,3d
GET kibana_sample_data_ecommerce/_search { "size": 1000, "query": { "bool": { "must": [ {"term": { "currency": "EUR" }} ], "filter": { "range": { "order_date": { "gte": "2020-01-25T23:45:36.000+00:00", "lte": "2020-02-01T23:45:36.000+00:00" } } } } } }
使用must过滤时间范围,code
GET kibana_sample_data_ecommerce/_search { "size": 1000, "query": { "bool": { "must": [ {"term": { "currency": "EUR" }}, {"range": { "order_date": { "gte": "2020-01-25T23:45:36.000+00:00", "lte": "2020-02-01T23:45:36.000+00:00" } }} ] } } }
查询的结果都是,blog
{ "took" : 25, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1087, "relation" : "eq" }, ...
上一节你已经知道了must和filter的基本用法和区别。简单来说,若是你的业务场景不须要算分,使用filter能够真的让你的查询效率飞起来。索引
为了说明filter查询高效的缘由,咱们须要引入ES的一个概念query context
和filter context
。ip
query context
query context
关注的是,文档到底有多匹配查询的条件,这个匹配的程度是由相关性分数决定的,分数越高天然就越匹配。因此这种查询除了关注文档是否知足查询条件,还须要额外的计算相关性分数.
filter context
filter context
关注的是,文档是否匹配查询条件,结果只有两个,是和否。没有其它额外的计算。它经常使用的一个场景就是过滤时间范围。
而且filter context会自动被ES缓存结果,效率进一步提升。
对于bool查询,must使用的就是query context
,而filter使用的就是filter context
。
咱们能够经过一个示例验证下。继续使用第一节的例子,咱们经过kibana自带的search profiler
来看看ES的查询的详细过程。
使用must查询的执行过程是这样的:
能够明显看到,这次查询计算了相关性分数,并且score的部分占据了查询时间的10分之一左右。
filter的查询我就不截图了,区别就是score这部分是0,也就是不计算相关性分数。
除了是否计算相关性算分的差异,常常使用的过滤器将被Elasticsearch自动缓存,以提升性能。
我本身曾经在一个项目中,对一个业务查询场景作了这种优化,当时线上的索引文档数量大概是3000万左右,改为filter以后,查询的速度几乎快了一倍。
我截了几张图,你来感觉下。
咱们应该根据本身的实际业务场景选择合适的查询语句,在某些不须要相关性算分的查询场景,尽可能使用filter context
可让你的查询更加高效。