英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/combining-filters.html
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
组合过滤器edit
前面的两个例子都是单个过滤器(filter)的使用方式。 在实际应用中,我们很有可能会过滤多个值或字段。比方说,怎样用 Elasticsearch 来表达下面的 SQL ?
SELECT product FROM products WHERE (price = 20 OR productID = "XHDK-A-1293-#fJ3") AND (price != 30)
这种情况下,我们需要 bool
(布尔)过滤器。 这是个 复合过滤器(compound filter) ,它可以接受多个其他过滤器作为参数,并将这些过滤器结合成各式各样的布尔(逻辑)组合。
布尔过滤器edit
一个 bool
过滤器由三部分组成:
{ "bool" : { "must" : [], "should" : [], "must_not" : [], } }
-
must
-
所有的语句都 必须(must) 匹配,与
AND
等价。 -
must_not
-
所有的语句都 不能(must not) 匹配,与
NOT
等价。 -
should
-
至少有一个语句要匹配,与
OR
等价。
就这么简单! 当我们需要多个过滤器时,只须将它们置入 bool
过滤器的不同部分即可。
一个 bool
过滤器的每个部分都是可选的(例如,我们可以只有一个 must
语句),而且每个部分内部可以只有一个或一组过滤器。
用 Elasticsearch 来表示本部分开始处的 SQL 例子,将两个 term
过滤器置入 bool
过滤器的 should
语句内,再增加一个语句处理 NOT
非的条件:
GET /my_store/products/_search { "query" : { "filtered" : { "filter" : { "bool" : { "should" : [ { "term" : {"price" : 20}}, { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} ], "must_not" : { "term" : {"price" : 30} } } } } } }
注意,我们仍然需要一个 |
|
在 |
|
如果一个产品的价格是 |
我们搜索的结果返回了 2 个命中结果,两个文档分别匹配了 bool
过滤器其中的一个条件:
嵌套布尔过滤器edit
尽管 bool
是一个复合的过滤器,可以接受多个子过滤器,需要注意的是 bool
过滤器本身仍然还只是一个过滤器。 这意味着我们可以将一个 bool
过滤器置于其他 bool
过滤器内部,这为我们提供了对任意复杂布尔逻辑进行处理的能力。
对于以下这个 SQL 语句:
SELECT document FROM products WHERE productID = "KDKE-B-9947-#kL5" OR ( productID = "JODL-X-1937-#pV7" AND price = 30 )
我们将其转换成一组嵌套的 bool
过滤器:
GET /my_store/products/_search { "query" : { "filtered" : { "filter" : { "bool" : { "should" : [ { "term" : {"productID" : "KDKE-B-9947-#kL5"}}, { "bool" : { "must" : [ { "term" : {"productID" : "JODL-X-1937-#pV7"}}, { "term" : {"price" : 30}} ] }} ] } } } } }
因为 |
|
这两个 |
得到的结果有两个文档,它们各匹配 should
语句中的一个条件:
"hits" : [ { "_id" : "2", "_score" : 1.0, "_source" : { "price" : 20, "productID" : "KDKE-B-9947-#kL5" } }, { "_id" : "3", "_score" : 1.0, "_source" : { "price" : 30, "productID" : "JODL-X-1937-#pV7" } } ]
这只是个简单的例子,但足以展示布尔过滤器可以用来作为构造复杂逻辑条件的基本构建模块。