zoukankan      html  css  js  c++  java
  • elasticsearch 深入 —— Top Hits Aggregation

    Top Hits Aggregation

    top_hits指标聚合器跟踪正在聚合的最相关文档。 此聚合器旨在用作子聚合器,以便可以按桶聚合最匹配的文档。
    top_hits聚合器可以有效地用于通过桶聚合器按特定字段对结果集进行分组。 一个或多个存储桶聚合器确定结果集被切入的属性。

    选项

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

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

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

    实例

    下面来看看具体的例子,就知道怎么回事了,使用起来很简单。

    • 先准备索引和数据,这里以菜谱为例,name:菜谱名,type 为菜系,rating 为用户的累积平均评分
    PUT recipes
    POST /recipes/type/_mapping
    {
      "properties": {
        "name":{
          "type": "text"
        },
        "rating":{
          "type": "float"
        },"type":{
          "type": "keyword"
        }
      }
    }
    /recipes/_bulk
    { "index":  { "_index": "recipes", "_type": "type"}}
    {"name":"清蒸鱼头","rating":1,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"剁椒鱼头","rating":2,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"红烧鲫鱼","rating":3,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"鲫鱼汤(辣)","rating":3,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"鲫鱼汤(微辣)","rating":4,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"鲫鱼汤(变态辣)","rating":5,"type":"湘菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"广式鲫鱼汤","rating":5,"type":"粤菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"鱼香肉丝","rating":2,"type":"川菜"}
    { "index":  { "_index": "recipes", "_type": "type"}} 
    {"name":"奶油鲍鱼汤","rating":2,"type":"西菜"}
    
    • 现在我们看看普通的查询效果是怎么样的,搜索关键字带“鱼”的菜,返回3条数据
    POST recipes/type/_search
    {
      "query": {"match": {
        "name": "鱼"
      }},"size": 3
    } 
    

    全是湘菜,我的天,最近上火不想吃辣,这个第一页的结果对我来说就是垃圾,如下:

    {
      "took": 2,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": 0.26742277,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYF_OA-dG63Txsd",
            "_score": 0.26742277,
            "_source": {
              "name": "鲫鱼汤(变态辣)",
              "rating": 5,
              "type": "湘菜"
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHXO_OA-dG63Txsa",
            "_score": 0.19100356,
            "_source": {
              "name": "红烧鲫鱼",
              "rating": 3,
              "type": "湘菜"
            }
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHWy_OA-dG63TxsZ",
            "_score": 0.19100356,
            "_source": {
              "name": "剁椒鱼头",
              "rating": 2,
              "type": "湘菜"
            }
          }
        ]
      }
    }
    
    • 我们再看看,这次我想加个评分排序,大家都喜欢的是那些,看看有没有喜欢吃的,执行查询:
    POST recipes/type/_search
    {
      "query": {"match": {
        "name": "鱼"
      }},"sort": [
        {
          "rating": {
            "order": "desc"
          }
        }
      ],"size": 3
    } 
    

    结果稍微好点了,不过3个里面2个是湘菜,还是有点不合适,结果如下:

    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYF_OA-dG63Txsd",
            "_score": null,
            "_source": {
              "name": "鲫鱼汤(变态辣)",
              "rating": 5,
              "type": "湘菜"
            },
            "sort": [
              5
            ]
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHYW_OA-dG63Txse",
            "_score": null,
            "_source": {
              "name": "广式鲫鱼汤",
              "rating": 5,
              "type": "粤菜"
            },
            "sort": [
              5
            ]
          },
          {
            "_index": "recipes",
            "_type": "type",
            "_id": "AVoESHX7_OA-dG63Txsc",
            "_score": null,
            "_source": {
              "name": "鲫鱼汤(微辣)",
              "rating": 4,
              "type": "湘菜"
            },
            "sort": [
              4
            ]
          }
        ]
      }
    }
    
    • 现在我知道了,我要看看其他菜系,这家不是还有西餐、广东菜等各种菜系的么,来来,帮我每个菜系来一个菜看看,换 terms agg 先得到唯一的 term 的 bucket,再组合 top_hits agg,返回按评分排序的第一个 top hits,有点复杂,没关系,看下面的查询就知道了:
    GET recipes/type/_search
    {
      "query": {
        "match": {
          "name": "鱼"
        }
      },
      "sort": [
        {
          "rating": {
            "order": "desc"
          }
        }
      ],"aggs": {
        "type": {
          "terms": {
            "field": "type",
            "size": 10
          },"aggs": {
            "rated": {
              "top_hits": {
                "sort": [{
                  "rating": {"order": "desc"}
                }], 
                "size": 1
              }
            }
          }
        }
      }, 
      "size": 0,
      "from": 0
    } 
    

    看下面的结果,虽然 json 结构有点复杂,不过总算是我们想要的结果了,湘菜、粤菜、川菜、西菜都出来了,每样一个,不重样:

    {
      "took": 4,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "type": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": "湘菜",
              "doc_count": 6,
              "rated": {
                "hits": {
                  "total": 6,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYF_OA-dG63Txsd",
                      "_score": null,
                      "_source": {
                        "name": "鲫鱼汤(变态辣)",
                        "rating": 5,
                        "type": "湘菜"
                      },
                      "sort": [
                        5
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": "川菜",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYr_OA-dG63Txsf",
                      "_score": null,
                      "_source": {
                        "name": "鱼香肉丝",
                        "rating": 2,
                        "type": "川菜"
                      },
                      "sort": [
                        2
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": "粤菜",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHYW_OA-dG63Txse",
                      "_score": null,
                      "_source": {
                        "name": "广式鲫鱼汤",
                        "rating": 5,
                        "type": "粤菜"
                      },
                      "sort": [
                        5
                      ]
                    }
                  ]
                }
              }
            },
            {
              "key": "西菜",
              "doc_count": 1,
              "rated": {
                "hits": {
                  "total": 1,
                  "max_score": null,
                  "hits": [
                    {
                      "_index": "recipes",
                      "_type": "type",
                      "_id": "AVoESHY3_OA-dG63Txsg",
                      "_score": null,
                      "_source": {
                        "name": "奶油鲍鱼汤",
                        "rating": 2,
                        "type": "西菜"
                      },
                      "sort": [
                        2
                      ]
                    }
                  ]
                }
              }
            }
          ]
        }
      }
    }
    
  • 相关阅读:
    IE6,IE7 DIV高度技巧(div高度兼容问题)
    QQ在线咨询插件
    Singleton单件 (创建型模式)
    SQL Server ErrorLog 错误日志(如果数据库所占空间变大)
    IE6 div标签height的Bug
    c# 中 Volatile关键字理解
    翻译:SWFObject 2.0官方文档(用来做flash的js)
    已连接到空闲例程的问题解决办法
    Oracle 的一个非常好的触发器例子
    Oracle中表的非常全面的操作
  • 原文地址:https://www.cnblogs.com/gmhappy/p/11864044.html
Copyright © 2011-2022 走看看