5.1.14. 热门聚合
最热点聚合
top_hits
度量聚合器跟踪要聚合的最相关文档。该聚合器旨在用作子聚合器,以便可以按存储分区汇总最匹配的文档。
top_hits
聚合器可以有效地用于通过存储桶聚合器按某些字段对结果集进行分组。一个或多个存储桶聚合器确定将结果集切成哪些属性。
选项
from
- 与要获取的第一个结果的偏移量。size
- 每个存储区要返回的最匹配匹配项的最大数目。默认情况下,返回前三个匹配项。sort
- 应该如何对最匹配的匹配进行排序。默认情况下,命中按主要查询的分数排序。
支持每次点击功能
top_hits聚合返回常规搜索命中,因为可以支持许多每次命中功能:
示例
在以下示例中,我们按类型对销售进行分组,并且按类型将最后的销售显示。对于每个销售,源中仅包含日期和价格字段。
POST /sales/_search?size=0
{
"aggs": {
"top_tags": {
"terms": {
"field": "type",
"size": 3
},
"aggs": {
"top_sales_hits": {
"top_hits": {
"sort": [
{
"date": {
"order": "desc"
}
}
],
"_source": {
"includes": [ "date", "price" ]
},
"size" : 1
}
}
}
}
}
}
可能的响应:
{
...
"aggregations": {
"top_tags": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "hat",
"doc_count": 3,
"top_sales_hits": {
"hits": {
"total" : {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "sales",
"_type": "_doc",
"_id": "AVnNBmauCQpcRyxw6ChK",
"_source": {
"date": "2015/03/01 00:00:00",
"price": 200
},
"sort": [
1425168000000
],
"_score": null
}
]
}
}
},
{
"key": "t-shirt",
"doc_count": 3,
"top_sales_hits": {
"hits": {
"total" : {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "sales",
"_type": "_doc",
"_id": "AVnNBmauCQpcRyxw6ChL",
"_source": {
"date": "2015/03/01 00:00:00",
"price": 175
},
"sort": [
1425168000000
],
"_score": null
}
]
}
}
},
{
"key": "bag",
"doc_count": 1,
"top_sales_hits": {
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "sales",
"_type": "_doc",
"_id": "AVnNBmatCQpcRyxw6ChH",
"_source": {
"date": "2015/01/01 00:00:00",
"price": 150
},
"sort": [
1420070400000
],
"_score": null
}
]
}
}
}
]
}
}
}
字段折叠示例
字段折叠或结果分组是一项功能,可将结果集按逻辑分组,然后按组返回顶级文档。组的顺序由组中第一个文档的相关性确定。在Elasticsearch中,这可以通过将top_hits
聚合器包装为子聚合器的存储桶聚合器来实现。
在下面的示例中,我们搜索了所有已爬的网页。对于每个网页,我们存储该网页所属的正文和域名。通过在domain
字段中定义terms
聚合器,我们可以按域对网页结果集进行分组。然后将top_hits
聚合器定义为子聚合器,以便按存储桶收集最匹配的匹配项。
还定义了max
聚合器,terms
聚合器的排序功能使用该聚合器根据存储桶中最相关文档的相关性顺序返回存储桶。
POST /sales/_search
{
"query": {
"match": {
"body": "elections"
}
},
"aggs": {
"top_sites": {
"terms": {
"field": "domain",
"order": {
"top_hit": "desc"
}
},
"aggs": {
"top_tags_hits": {
"top_hits": {}
},
"top_hit" : {
"max": {
"script": {
"source": "_score"
}
}
}
}
}
}
}
目前需要最大(或最小)聚合器,以确保根据每个域中最相关网页的分数对术语聚合器中的存储桶进行排序。遗憾的是,top_hits 聚合器尚不能在术语聚合器的 order 选项中使用。
top_hits 支持嵌套或反向嵌套聚合器
如果top_hits
聚合包在nested
或reverse_nested
聚合中,则返回嵌套的匹配数据。从某种意义上说,嵌套命中是隐藏的迷你文档,它们是常规文档的一部分,在映射中已配置了嵌套字段类型。如果top_hits
聚合包装在nested
或reverse_nested
聚合中,则可以取消隐藏这些文档。在嵌套类型映射中了解有关嵌套的更多信息。
如果已配置嵌套类型,则单个文档实际上将被索引为多个 Lucene 文档,并且它们共享相同的ID。为了确定嵌套匹配的身份,除了ID之外,还需要更多的信息,因此这就是嵌套匹配还包括其嵌套身份的原因。嵌套标识保留在搜索匹配的_nested
字段下,并包括数组字段和嵌套匹配所属的数组字段中的偏移量。偏移量基于零。
让我们看看它如何与真实例子一起工作。考虑以下映射:
PUT /sales
{
"mappings": {
"properties" : {
"tags" : { "type" : "keyword" },
"comments" : {
"type" : "nested",
"properties" : {
"username" : { "type" : "keyword" },
"comment" : { "type" : "text" }
}
}
}
}
}
- 注释是一个数组,用于在产品对象下保存嵌套文档 .
一些文档
PUT /sales/_doc/1?refresh
{
"tags": ["car", "auto"],
"comments": [
{"username": "baddriver007", "comment": "This car could have better brakes"},
{"username": "dr_who", "comment": "Where's the autopilot? Can't find it"},
{"username": "ilovemotorbikes", "comment": "This car has two extra wheels"}
]
}
现在可以执行以下顶级点击聚合(包装在嵌套聚合中):
POST /sales/_search
{
"query": {
"term": { "tags": "car" }
},
"aggs": {
"by_sale": {
"nested" : {
"path" : "comments"
},
"aggs": {
"by_user": {
"terms": {
"field": "comments.username",
"size": 1
},
"aggs": {
"by_nested": {
"top_hits":{}
}
}
}
}
}
}
}
具有嵌套匹配项的热门匹配项摘要,位于数组字段comments
的第一个插槽中:
{
...
"aggregations": {
"by_sale": {
"by_user": {
"buckets": [
{
"key": "baddriver007",
"doc_count": 1,
"by_nested": {
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.3616575,
"hits": [
{
"_index": "sales",
"_type" : "_doc",
"_id": "1",
"_nested": {
"field": "comments",
"offset": 0
},
"_score": 0.3616575,
"_source": {
"comment": "This car could have better brakes",
"username": "baddriver007"
}
}
]
}
}
}
...
]
}
}
}
}
- 包含嵌套匹配项的数组字段的名称
- 如果嵌套命中在包含数组中
- 嵌套匹配的来源
如果请求_source
,则返回嵌套对象源的一部分,而不是文档的整个源。还可以通过位于nested
或reverse_nested
聚合中的top_hits
聚合访问嵌套对象内部级别上的存储字段。
仅嵌套匹配在匹配中具有_nested
字段,非嵌套(常规)匹配将没有_nested
字段。
如果未启用_source
,则_nested
中的信息还可用于解析其他地方的原始源。
在下面的示例中,嵌套匹配项位于nested_grand_child_field
字段的第一个插槽中,然后位于nested_child_field
字段的第二个慢速位置中:
...
"hits": {
"total" : {
"value": 2565,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "a",
"_type": "b",
"_id": "1",
"_score": 1,
"_nested" : {
"field" : "nested_child_field",
"offset" : 1,
"_nested" : {
"field" : "nested_grand_child_field",
"offset" : 0
}
}
"_source": ...
},
...
]
}
...
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。