3.5 查询结果的过滤

本书已经介绍了如何使用不同的条件和查询来构建查询并搜索数据。我们还熟知了评分(参

见1.1.3节),它告诉我们在给定的查询中,哪些文档更重要以及查询文本如何影响排序。然而,

有时我们可能要在不影响最后分数的情况下,选择索引中的某个子集,这就要使用过滤器(当然

不是唯一的原因)。

老实说,应该尽可能使用过滤器。过滤器不影响评分,而得分计算让搜索变得复杂,而且需

要CPU资源。另一方面,过滤是一种相对简单的操作。由于过滤应用在整个索引的内容上,过滤

的结果独立于找到的文档,也独立于文档之间的关系。过滤器很容易被缓存,从而进一步提高过

滤查询的整体性能。

 { "query": { "filtered" : { "query" : { "match" : { "title" : "Catch-22" } }, "filter" : { "term" : { "year" : 1961 } } } } }

 

3.5.2

过滤器类型

1. 范围过滤器

范围过滤器可以用来限制只搜索那些字段值在给定边界之间的文档。例如,为了创建一个过 滤器来过滤只在1930~1990年之间出版的图书,在查询中加入以下部分:

{ "post_filter" : { "range" : { "year" : { "gte": 1930, "lte": 1990 } } } }

2.missing过滤器

3.exists过滤器

exists过滤器非常简单。它过滤掉给定字段上没有值的文档。比如,考虑下面的代码:

{ "post_filter" : { "exists" : { "field": "year" } } }

上述过滤器将只返回year字段有值的文档。

missing过滤器跟exists过滤器相反,它过滤掉给定字段上有值的文档。然而,它还有一 些额外的功能。除了选择指定字段缺失的文档,可以指定Elasticsearch对空字段的定义。这有助 于在输入数据中包含null、EMPTY、not-defined等词条的情况。我们修改先前的例子,找没 有定义year字段、或者year字段为0的那些文档。修改过的过滤器将如下所示:

{ "post_filter" : { "missing" : { "field": "year", "null_value": 0, "existence": true } } }

在前面的示例中,有两个额外参数。existence参数告诉Elasticsearch应该检查指定字段上 存在值的文档,null_value参数定义了应该被视为空的额外值。如果你没有定义null_value, existence将被设为默认值;所以,在这个例子中可以省略existence。

4.脚本过滤器

有时,我们想要通过计算值来过滤文档。一个例子是:可以过滤掉所有发表在一个世纪以前 的书。使用脚本过滤器来实现,如下所示:

{ "post_filter" : { "script" : { "script" : "now - doc['year'].value > 100", "params" : { "now" : 2012 } } } } }

可以看到,我们使用了一个简单的脚本来计算值,并从中过滤数据。

5.类型过滤器

想限制返回文档的类型为book,使用下列过滤器:

{ "post_filter" : { "type": { "value" : "book" } } }

类型过滤器专门用来限制文档的类型。当查询运行在多个索引上,或单个索引但有很多类型 时,可以使用这个过滤器。

6.限定过滤器

{ "post_filter" : { "limit" : { "value" : 1 } } }

当我们对分片数量使用默认设置时,上述过滤器返回5个文档。因为在Elasticsearch中,索引 默认分为5个分片。查询分别运行在各个分片上,而每个分片最多返回1个文档。

限定过滤器限定单个分片返回的文档数目。

7.标识符过滤器

要排除标识符等于1的文档, 可使用类似下面的代码:

 { "post_filter": { "ids" : { "type": ["book"], "values": [1] } } }

需要过滤成若干具体的文档时,可以使用标识符过滤器。

8.

Elasticsearch支持下列专用过滤器:

 bool过滤器;

 geo_shape过滤器;

 has_child过滤器;

 has_parent过滤器;

 ids过滤器;

 indices过滤器;

 match_all过滤器;

 nested过滤器;

 prefix过滤器;

 range过滤器;

 regexp过滤器;

 term过滤器;

 terms过滤器。

9.

组合过滤器

{
"post_filter": {
"not": {
"and": [
{
"term": {
"title": "Catch-22"
}
},
{
"or": [
{
"range": {
"year": {
"gte": 1930,
"lte": 1990
}
}
},
{
"term": {
"available": true
}
}
]
}
]
}
}
}
10.
命名过滤器
记住在大多数情况下,filtered查询比post_filter更快。所以在可能的 情况下,尽可能使用filtered查询。