zoukankan      html  css  js  c++  java
  • ElasticSearch

    摘要

    聚合范围限定还有一个自然的扩展就是过滤。因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。

    版本

    elasticsearch版本: elasticsearch-2.x

    内容

    聚合范围限定还有一个自然的扩展就是过滤。因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。

    Filtered 查询(Filtered Query)

    如果我们想找到售价在 $10,000 美元之上的所有汽车同时也为这些车计算平均售价,可以简单地使用一个 filtered 查询:

      GET /cars/transactions/_search
      {
          "size" : 0,
          "query" : {
              "filtered": {
                  "filter": {
                      "range": {
                          "price": {
                              "gte": 10000
                          }
                      }
                  }
              }
          },
          "aggs" : {
              "single_avg_price": {
                  "avg" : { "field" : "price" }
              }
          }
      }

    这正如我们在前面章节中讨论过那样,从根本上讲,使用 filtered 查询和使用 match 查询没有任何区别。查询(包括了一个过滤器)返回一组文档的子集,聚合正是操作这些文档。

    过滤桶(Filter Bucket)

    但是如果我们只想对聚合结果过滤怎么办?假设我们正在创建一个可以搜索汽车经销商的页面,我们希望显示用户搜索的结果,但是我们同时也想在页面上提供更丰富的信息,包括(与搜索匹配的)上个月度汽车的平均售价

    这里我们无法简单的做范围限定,因为有两个不同的条件。搜索结果必须是 ford,但是聚合结果必须满足 ford AND sold > now - 1M

    为了解决这个问题,我们可以用一种特殊的桶,叫做过滤桶。我们可以指定一个过滤桶,当文档满足过滤桶的条件时,我们将其加入到桶内。

    查询结果如下:

      GET /cars/transactions/_search
      {
         "size" : 0,
         "query":{
            "match": {
               "make": "ford"
            }
         },
         "aggs":{
            "recent_sales": {
               "filter": { #1
                  "range": {
                     "sold": {
                        "from": "now-1M"
                     }
                  }
               },
               "aggs": {
                  "average_price":{
                     "avg": {
                        "field": "price" #2
                     }
                  }
               }
            }
         }
      }

    #1 使用过滤桶在查询范围基础上应用过滤器。

    #2 avg 度量只会对 ford 和 一月以内售出 的文档计算平均售价。

    因为 filter 桶和其他桶的操作方式一样,所以可以随意将其他桶和度量嵌入其中。所有嵌套的组件都会 “继承” 这个过滤,这使我们可以按需针对聚合过滤出选择部分。

    展示过滤器(Post Filter)

    目前为止,我们可以同时对搜索结果和聚合结果进行过滤(一个 filtered 查询),以及针对聚合结果的一部分进行过滤(filter 桶)

    我们可能会想,“有只对搜索结果进行过滤而不过滤聚合结果的方式吗?”答案是使用 post_filter

    它是顶层搜索请求元素接收一个过滤器。这个过滤器在查询之后执行(这正是该过滤器的名字的由来:它在查询之后(post)执行)。正因为它在查询之后执行,它对查询范围没有任何影响,所以对聚合也不会有任何影响。

    我们可以利用这个行为对查询条件应用更多的过滤器,而不会影响其他的操作,就如 UI 上的各个分类面。让我们为汽车经销商设计另外一个搜索页面,这个页面允许用户搜索汽车同时可以根据颜色来过滤。颜色的选项是通过聚合获得的:

      GET /cars/transactions/_search
      {
          "size" : 0,
          "query": {
              "match": {
                  "make": "ford"
              }
          },
          "post_filter": {    #1
              "term" : {
                  "color" : "green"
              }
          },
          "aggs" : {
              "all_colors": {
                  "terms" : { "field" : "color" }
              }
          }
      }

    #1 post_filter 元素是顶层元素而且仅对命中结果进行过滤。

    查询部分找到所有的 ford 汽车,然后用 terms 聚合创建一个颜色列表。因为聚合对查询范围进行操作,颜色列表与福特汽车有的颜色相对应。

    最后,post_filter 会过滤搜索结果,只展示绿色福特汽车。这在查询执行过后发生,所以聚合不受影响。

    这通常对 UI 的连贯一致性很重要,可以想象用户在界面商选择了一类颜色(比如:green 绿色),期望的是搜索结果已经被过滤了,而不是过滤界面上的选项。如果我们应用 filtered 查询,界面会马上变成只显示 green 作为选项,这不是用户想要的!

    警告
    性能考虑(Performance consideration)

    只在我们需要区别过滤搜索结果和聚合结果时使用 post_filter,有时用户会在普通搜索使用 post_filter

    不要这么做!post_filter 的特性是在查询之后执行,所以任何过滤所带来的好处(比如缓存)都会完全失去。

    post_filter 应该只在我们需要不同过滤时,只与聚合一起使用。

    小结(Recap)

    选择合适类型的过滤(如:搜索命中、聚合或两者兼有)通常和我们期望如何表现用户交互有关。选择合适的过滤器(或组合)取决于我们期望如何将结果呈现给用户。

    • filtered 查询同时影响搜索结果和聚合结果。
    • filter 桶影响聚合。
    • post_filter 只影响搜索结果。

    参考

    elastic.co:
    Filtering Queries and Aggregations

  • 相关阅读:
    姐姐的vue(1)
    LeetCode 64. Minimum Path Sum 20170515
    LeetCode 56. 56. Merge Intervals 20170508
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 24. Swap Nodes in Pairs 20170424
    LeetCode 19. Remove Nth Node From End of List 20170417
    LeetCode No.9 Palindrome Number 20170410
    LeetCode No.8. String to Integer (atoi) 2017/4/10(补上一周)
    LeetCode No.7 Reverse Integer 2017/3/27
    LeetCode No.4 Median of Two Sorted Arrays 20170319
  • 原文地址:https://www.cnblogs.com/chuanheng/p/elasticsearch_aggs.html
Copyright © 2011-2022 走看看