【问题标题】:Multiple filters and an aggregate in elasticsearch弹性搜索中的多个过滤器和聚合
【发布时间】:2014-07-11 12:28:29
【问题描述】:

如何在 elasticsearch 中使用与聚合相关的过滤器?

官方文档只给出了filter 和aggregations 的简单示例,并且没有对查询 dsl 的正式描述 - 比较它,例如postgres documentation。

通过尝试,我发现以下查询被 elasticsearch 接受(没有解析错误),但忽略了给定的过滤器:

{
  "filter": {
    "and": [
      {
        "term": {
          "_type": "logs"
        }
      },
      {
        "term": {
          "dc": "eu-west-12"
        }
      },
      {
        "term": {
          "status": "204"
        }
      },
      {
        "range": {
          "@timestamp": {
            "from": 1398169707,
            "to": 1400761707
          }
        }
      }
    ]
  },
  "size": 0,
  "aggs": {
    "time_histo": {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "1h"
      },
      "aggs": {
        "name": {
          "percentiles": {
            "field": "upstream_response_time",
            "percents": [
              98.0
            ]
          }
        }
      }
    }
  }
}

有些人建议使用query 而不是filter。但官方文档一般推荐the opposite 用于过滤精确值。 query 的另一个问题:虽然过滤器提供 and,但 query 没有。

谁能指出我的文档、博客或书籍,它们描述了编写非平凡的查询:至少是一个聚合加上多个过滤器。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我最终使用了 filter aggregation - 未过滤的查询。所以现在我有 3 个嵌套的 aggs 元素。

    我也使用bool 过滤器而不是@alex-brasetvik 推荐的and,因为http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/

    我的最终实现:

    {
      "aggs": {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "_type": "logs"
                  }
                },
                {
                  "term": {
                    "dc": "eu-west-12"
                  }
                },
                {
                  "term": {
                    "status": "204"
                  }
                },
                {
                  "range": {
                    "@timestamp": {
                      "from": 1398176502000,
                      "to": 1400768502000
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "time_histo": {
              "date_histogram": {
                "field": "@timestamp",
                "interval": "1h"
              },
              "aggs": {
                "name": {
                  "percentiles": {
                    "field": "upstream_response_time",
                    "percents": [
                      98.0
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "size": 0
    }
    

    【讨论】:

    【解决方案2】:

    将您的过滤器放在filtered-query 中。

    顶级filter 仅用于过滤搜索命中,而不用于过滤构面/聚合。由于这种相当常见的混淆,它在 1.0 中被重命名为 post_filter。

    另外,您可能想查看这篇文章,了解为什么您经常要使用 bool 而不是 and/or:http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/

    【讨论】:

      【解决方案3】:

      更多关于@geekQ 的回答:支持带有空格字符的过滤器字符串,用于多词搜索,使用下面:

      {   "aggs": {
          "aggresults": {
            "filter": {
              "bool": {
                "must": [
                  {
                    "match_phrase": {
                      "term_1": "some text with space 1"
                    }
                  },
                  {
                    "match_phrase": {
                      "term_2": "some text with also space 2"
                    }
                  }
                ]
              }
            },
            "aggs" : {
                  "all_term_3s" : {
                      "terms" : {
                          "field":"term_3.keyword",
                          "size" : 10000,
                          "order" : {
                              "_term" : "asc" 
                          }
                      }
                 }
              }
          }   },   "size": 0 }
      

      【讨论】:

        【解决方案4】:

        仅供参考,对于7.2的版本,我尝试了如下实现多个过滤器进行聚合:

        POST movies/_search?size=0
        {
          "size": 0,
          "aggs": {
            "test": {
              "filter": {
                "bool": {
                  "must": {
                    "term": {
                      "genre": "action"
                    }
                  },
                  "filter": {
                    "range": {
                      "year": {
                        "gte": 1800,
                        "lte": 3000
                      }
                    }
                  }
                }
              },
              "aggs": {
                "year_hist": {
                  "histogram": {
                    "field": "year",
                    "interval": 50
                  }
                }
              }
            }
          }
        }
        

        【讨论】:

        • 有没有办法在过滤器中输入 2 个词?所以在 must.term 里面我想添加 "term":{"genre":"action", "country":"USA"} 这样的东西。
        • @makewhite 似乎 should 配置正确的 minimum_should_match 会有所帮助。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多