在本节中,您将了解一种从筛选器衍生出来的模式,这种模式被广泛应用于搜索实现中,称为分面搜索。其目的是让用户运行查询,然后将建议的过滤器列表与查询结果一起呈现给用户。
下面的截图显示了一个左侧边栏,上面有目前在应用程序中实现的两个过滤器的切面。

下面是分面搜索结果的详情。请注意,每个条目都显示为一个可点击的链接,将过滤器添加到当前搜索中。每个面还会报告其包含的结果数量。

学期汇总
在 Elasticsearch 中,分面搜索是通过聚合功能实现的。其中一种支持的聚合方法是根据某些标准将搜索结果分成若干个桶。文件桶列表(每个文件桶包括其包含的文件数量)将用于渲染分面侧边栏。
最简单的桶聚合类型是为每个关键字定义桶。这种被称为术语聚合的类型非常适合为category 字段创建数据桶。下面是应用程序的搜索请求,经过扩展后可以搜索类别聚合:
唯一的变化是增加了aggs 选项。每个聚合都有一个名称,本例中为category-agg 。terms 聚合表示应按关键字进行筛选。与筛选器一样,category 字段必须以category.keyword 的形式给出,以便使用与字段相关的关键字子类型。
对聚合请求的响应有一个aggregations 字段,其中包含聚合结果。下面是对上述请求示例的响应:
教程应用程序中包含的index.html模板已设计用于在左侧边栏中呈现聚合,而在此之前,左侧边栏是空的。为了简化模板逻辑,必须将上述响应中的数据转换成具有以下结构的字典:
下一个列表显示了如何将 Elasticsearch 聚合格式转换为上述简化字典,以及如何将转换后的字典发送到模板进行渲染:
如果您想知道,index.html包含以下逻辑来呈现aggs 字典:
这种实现方式采用的理念与呈现下一个和上一个分页按钮的理念类似。每个面都以表单的形式呈现,表单中的隐藏字段定义了带有相应附加过滤器的查询。例如,sharepoint 类别分面将在当前查询中添加category:sharepoint 。
在外观上,每个面中的提交按钮都是以链接的样式呈现的。
年份汇总
分类中使用的术语聚合对上一节中建立的年份过滤器不起作用,因为大家都记得,索引并没有将年份单独存储为关键字。相反,每篇文章的更新年份由updated_at 字段定义,该字段存储的是完整的日期。
在一长串可用的桶聚合中,日期直方图最适合这种使用情况。以下是更新后的聚合请求:
在这里,您可以看到aggs 字段添加了第二个聚合。该聚合的类型是date_histogram ,时间间隔设为year ,这样创建的每个数据桶都代表一年。format 选项用于配置每个水桶名称的格式,在本例中应只包括年份。
现在,回复中的aggregations 字段将包括两个部分:
第二次汇总还有一个小麻烦。key 字段并没有什么用处,因为对于日期间隔聚合来说,它是以毫秒为单位的。但幸运的是,在key_as_string 字段中提供了聚合中format 选项所给格式的日期。
以下是aggs 字典包括所有面的计算方法:
除了使用key_as_string 而不是key 外,还为年份刻面添加了一个条件,以剔除其中包含零文档的数据桶,因为显然没有必要将它们用作筛选器。
至此,分面搜索的实现就完成了。下面是handle_search() 函数的完整实现过程:
本教程中包含的分面搜索实现方式在设计时考虑到了简便性。Elasticsearch 中的聚合功能有很多可能性,我们还没有涉及,因此请务必查看文档,了解该功能的所有信息。
恭喜您,本教程的 "全文搜索 "部分已经结束!单击此处查看教程搜索应用程序到目前为止的状态。