Top Hits Aggregation

    top_hits 指标聚合器跟踪正在聚合的最相关文档。此聚合器旨在用作子聚合器,以便可以按桶聚合最匹配的文档。

    top_hits 聚合器可以有效地用于通过桶聚合器按特定字段对结果集进行分组。一个或多个存储桶聚合器确定结果集被切入的属性。

    Options

    • from - 要获取的第一个结果的偏移量。
    • size - 每个桶返回的最大匹配匹配数的最大数量。默认情况下,返回前三个匹配的结果。
    • sort - 如何对顶部匹配的结果进行排序。默认情况下,命中按主查询的分数排序。

    Supported per hit features 每个匹配功能支持

    top_hits 聚合返回常规搜索命中,因为可以支持许多每个命中功能:

    Example

    在以下示例中,我们按类型和每种类型对销售进行分组,以显示上次销售。对于每次销售,只有日期和价格字段包含在来源中。

    1. POST /sales/_search?size=0
    2. {
    3. "aggs": {
    4. "top_tags": {
    5. "terms": {
    6. "field": "type",
    7. "size": 3
    8. },
    9. "aggs": {
    10. "top_sales_hits": {
    11. "top_hits": {
    12. "sort": [
    13. {
    14. "date": {
    15. "order": "desc"
    16. }
    17. }
    18. ],
    19. "_source": {
    20. "includes": [ "date", "price" ]
    21. },
    22. "size" : 1
    23. }
    24. }
    25. }
    26. }
    27. }
    28. }

    可能的回应:

    1. {
    2. ...
    3. "aggregations": {
    4. "top_tags": {
    5. "doc_count_error_upper_bound": 0,
    6. "sum_other_doc_count": 0,
    7. "buckets": [
    8. {
    9. "key": "hat",
    10. "doc_count": 3,
    11. "top_sales_hits": {
    12. "hits": {
    13. "total" : {
    14. "value": 3,
    15. "relation": "eq"
    16. },
    17. "max_score": null,
    18. "hits": [
    19. {
    20. "_index": "sales",
    21. "_type": "_doc",
    22. "_id": "AVnNBmauCQpcRyxw6ChK",
    23. "_source": {
    24. "date": "2015/03/01 00:00:00",
    25. "price": 200
    26. },
    27. "sort": [
    28. 1425168000000
    29. ],
    30. "_score": null
    31. }
    32. ]
    33. }
    34. }
    35. },
    36. {
    37. "key": "t-shirt",
    38. "doc_count": 3,
    39. "top_sales_hits": {
    40. "hits": {
    41. "total" : {
    42. "value": 3,
    43. "relation": "eq"
    44. },
    45. "max_score": null,
    46. "hits": [
    47. {
    48. "_index": "sales",
    49. "_type": "_doc",
    50. "_id": "AVnNBmauCQpcRyxw6ChL",
    51. "_source": {
    52. "date": "2015/03/01 00:00:00",
    53. "price": 175
    54. },
    55. "sort": [
    56. 1425168000000
    57. ],
    58. "_score": null
    59. }
    60. ]
    61. }
    62. }
    63. },
    64. {
    65. "key": "bag",
    66. "doc_count": 1,
    67. "top_sales_hits": {
    68. "hits": {
    69. "total" : {
    70. "value": 1,
    71. "relation": "eq"
    72. },
    73. "max_score": null,
    74. "hits": [
    75. {
    76. "_index": "sales",
    77. "_type": "_doc",
    78. "_id": "AVnNBmatCQpcRyxw6ChH",
    79. "_source": {
    80. "date": "2015/01/01 00:00:00",
    81. "price": 150
    82. },
    83. "sort": [
    84. 1420070400000
    85. ],
    86. "_score": null
    87. }
    88. ]
    89. }
    90. }
    91. }
    92. ]
    93. }
    94. }
    95. }

    Filed collapse example

    字段折叠或结果分组是一种功能,可以将结果集逻辑分组到组中,每组返回顶级文档。组的排序由组中第一个文档的相关性决定。在Elasticsearch中,这可以通过将top_hits聚合器包装为子聚合器的桶聚合器来实现。

    在下面的示例中,我们搜索已抓取的网页。对于每个网页,我们存储主体和网页所属的域。通过在域字段上定义术语聚合器,我们按域分组网页的结果集。然后将top_hits聚合器定义为子聚合器,以便每个桶收集最匹配的匹配。

    还定义了最大聚合器,其由术语聚合器的订单特征用于通过桶中最相关文档的相关性顺序返回桶。

    1. POST /sales/_search
    2. {
    3. "query": {
    4. "match": {
    5. "body": "elections"
    6. }
    7. },
    8. "aggs": {
    9. "top_sites": {
    10. "terms": {
    11. "field": "domain",
    12. "order": {
    13. "top_hit": "desc"
    14. }
    15. },
    16. "aggs": {
    17. "top_tags_hits": {
    18. "top_hits": {}
    19. },
    20. "top_hit" : {
    21. "max": {
    22. "script": {
    23. "source": "_score"
    24. }
    25. }
    26. }
    27. }
    28. }
    29. }
    30. }

    目前需要最大(或最小)聚合器以确保根据每个域的最相关网页的分数来对术语聚合器中的桶进行排序。不幸的是,top_hits聚合器还不能在聚合器术语的顺序选项中使用。

    top_hits support in a nested or reverse_nested aggregator

    如果top_hits聚合器包装在嵌套或reverse_nested聚合器中,则返回嵌套的命中。嵌套命中在某种意义上是隐藏的迷你文档,它们是常规文档的一部分,在映射中已经配置了嵌套字段类型。如果top_hits聚合器包含在嵌套或reverse_nested聚合器中,则它能够取消隐藏这些文档。阅读有关嵌套类型映射中嵌套的更多信息。

    如果已配置嵌套类型,则单个文档实际上被索引为多个Lucene文档,并且它们共享相同的ID。为了确定嵌套命中的身份,需要的不仅仅是id,因此嵌套命中也包括它们的嵌套身份。嵌套标识保存在搜索匹配中的_nested字段下,并包括数组字段和嵌套匹配所属的数组字段中的偏移量。偏移量基于零。

    让我们看看它如何与真实样本一起工作。考虑以下映射:

    1. PUT /sales
    2. {
    3. "mappings": {
    4. "properties" : {
    5. "tags" : { "type" : "keyword" },
    6. "comments" : {
    7. "type" : "nested",
    8. "properties" : {
    9. "username" : { "type" : "keyword" },
    10. "comment" : { "type" : "text" }
    11. }
    12. }
    13. }
    14. }
    15. }

    comments :注释是一个数组,用于存放产品对象下的嵌套文档。

    还有一些文件:

    1. PUT /sales/_doc/1?refresh
    2. {
    3. "tags": ["car", "auto"],
    4. "comments": [
    5. {"username": "baddriver007", "comment": "This car could have better brakes"},
    6. {"username": "dr_who", "comment": "Where's the autopilot? Can't find it"},
    7. {"username": "ilovemotorbikes", "comment": "This car has two extra wheels"}
    8. ]
    9. }

    现在可以执行以下top_hits聚合(包装在嵌套聚合中):

    1. POST /sales/_search
    2. {
    3. "query": {
    4. "term": { "tags": "car" }
    5. },
    6. "aggs": {
    7. "by_sale": {
    8. "nested" : {
    9. "path" : "comments"
    10. },
    11. "aggs": {
    12. "by_user": {
    13. "terms": {
    14. "field": "comments.username",
    15. "size": 1
    16. },
    17. "aggs": {
    18. "by_nested": {
    19. "top_hits":{}
    20. }
    21. }
    22. }
    23. }
    24. }
    25. }
    26. }

    热门命中具有嵌套匹配的响应代码段,它位于数组字段注释的第一个插槽中:

    1. {
    2. ...
    3. "aggregations": {
    4. "by_sale": {
    5. "by_user": {
    6. "buckets": [
    7. {
    8. "key": "baddriver007",
    9. "doc_count": 1,
    10. "by_nested": {
    11. "hits": {
    12. "total" : {
    13. "value": 1,
    14. "relation": "eq"
    15. },
    16. "max_score": 0.3616575,
    17. "hits": [
    18. {
    19. "_index": "sales",
    20. "_type" : "_doc",
    21. "_id": "1",
    22. "_nested": {
    23. "field": "comments", #@1
    24. "offset": 0 #@2
    25. },
    26. "_score": 0.3616575,
    27. "_source": {
    28. "comment": "This car could have better brakes", #@3
    29. "username": "baddriver007"
    30. }
    31. }
    32. ]
    33. }
    34. }
    35. }
    36. ...
    37. ]
    38. }
    39. }
    40. }
    41. }

    @1: 包含嵌套匹配的数组字段的名称
    @2: 如果嵌套命中包含在数组中,则定位
    @3: 嵌套命中的来源

    如果请求_source,则仅返回嵌套对象的源部分,而不是文档的整个源。嵌套内部对象级别的存储字段也可通过驻留在嵌套或反向嵌入聚合器中的top_hits聚合器访问。

    只有嵌套的匹配在命中时会有一个_nested字段,非嵌套(常规)匹配将没有_nested字段。

    如果未启用_source,则_nested中的信息也可用于在其他位置解析原始源。

    如果在映射中定义了多个级别的嵌套对象类型,则_nested信息也可以是分层的,以便表示深度为两层或更多层的嵌套命中的标识。

    在下面的示例中,嵌套的命中位于字段nested_grand_child_field的第一个槽中,然后它位于nested_child_field字段的第二个缓冲区中:

    1. ...
    2. "hits": {
    3. "total" : {
    4. "value": 2565,
    5. "relation": "eq"
    6. },
    7. "max_score": 1,
    8. "hits": [
    9. {
    10. "_index": "a",
    11. "_type": "b",
    12. "_id": "1",
    13. "_score": 1,
    14. "_nested" : {
    15. "field" : "nested_child_field",
    16. "offset" : 1,
    17. "_nested" : {
    18. "field" : "nested_grand_child_field",
    19. "offset" : 0
    20. }
    21. }
    22. "_source": ...
    23. },
    24. ...
    25. ]
    26. }
    27. ...