首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么过滤器聚合是必需的?

为什么过滤器聚合是必需的?
EN

Stack Overflow用户
提问于 2017-04-11 11:01:02
回答 2查看 1.2K关注 0票数 2

在使用elasticsearch (5.3.0)时,我们在涉及几个嵌套聚合的查询中遇到内存不足问题。

我们从经验上发现,问题在于聚合是根据完整的索引计算的,而不是考虑到query块中指定的条件。后来,我们成功地运行了查询,将这些条件移动到一个filter聚合(参见文档)中,该聚合封装了所有原始的aggs。

为什么会有一个单独的语法呢?如果elasticsearch在填充存储桶时只考虑所有查询条件,岂不是更好吗?

如果我选择以这种方式将所有聚合查询包装在filter查询中,那么风险和/或限制是什么?逻辑上有什么不同吗?

注意:在我们的应用程序中,根本不关心文档评分。所有条件都有过滤文档的唯一目的,而不是对文档进行排序。我们确实根据文档计数或聚合度量来过滤存储桶。

编辑:有些人要求查询,如果他们帮助澄清情况,他们就在这里。请注意,这个问题是一般性的,而不是针对这一具体情况的。

代码语言:javascript
复制
{
  "query": {
    // we did try a filtering rather than a query with the same results
    "term": {
      "urlpath": "some_url_path.html"
    }
  },
  "aggs": {
    "agg_1": {
      "terms": {
        "size": 10,
        "order": {
          "sessions_number": "desc"
        },
        "field": "urlpath"
      },
      "aggs": {
        "sessions_number": {
          "cardinality": {
            "field": "session"
          }
        }
      }
    }
  }
}

及之后:

代码语言:javascript
复制
{
  "aggs": {
    "agg_0": {
      "filter": {
        "term": {
          "urlpath": "some_url_path.html"
        }
      },
      "aggs": {
        "agg_1": {
          "terms": {
            "size": 10,
            "order": {
              "sessions_number": "desc"
            },
            "field": "urlpath"
          },
          "aggs": {
            "sessions_number": {
              "cardinality": {
                "field": "session"
              }
            }
          }
        }
      }
    }
  }
}

EDIT2:如下面@Lusid所建议的,I尝试使用过滤器查询,但问题与此相同。

NOTE2:如果我们删除order子句,那么问题就不会产生了,而且对于过滤器而不是查询也是如此。这对我们来说是最令人惊讶的,因为应该只有一个桶,使任何订单变得琐碎。这使我相信,过滤不是在测试之前进行的,为此,我试图将所有的内容都封装在过滤聚合中。

EN

回答 2

Stack Overflow用户

发布于 2017-04-12 02:36:39

在第一个示例中,您实际上不是筛选数据,而是查询数据。这只会影响搜索结果的评分过程,而不影响聚合的过滤。

尽管ElasticSearch的最新版本已经结合了查询/筛选语法,但理解两者之间的区别仍然很重要。根据这里的文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html

查询上下文中使用的查询子句回答了“此文档与此查询子句的匹配程度如何?”除了决定文档是否匹配之外,查询子句还计算一个_score,表示文档相对于其他文档的匹配程度。 在筛选器上下文中,查询子句回答“此文档与此查询子句匹配吗?”答案是简单的“是”或“否”, - 没有计算分数。过滤器上下文主要用于过滤结构化数据。

构建第一个查询的更好方法是将过滤器包装在query.constant_scorequery.bool中,如下所示:

代码语言:javascript
复制
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "urlpath": "some_url_path.html"
        }
      }
    }
  },
  "aggs": {
    "agg_1": {
      "terms": {
        "size": 10,
        "order": {
          "sessions_number": "desc"
        },
        "field": "urlpath"
      },
      "aggs": {
        "sessions_number": {
          "cardinality": {
            "field": "session"
          }
        }
      }
    }
  }
}

有关这两种选择的更多信息如下:

常量分数查询:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html

Bool查询(筛选部分):https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

当然,拥有这两个选项的好处是,您可以为整个搜索应用一个总体筛选器,但是可以进一步进行筛选聚合。

希望这能有所帮助!

编辑:由于在查询中使用过滤器,I主要是解决过滤器背后的原因,没有按照您在集合中所期望的方式工作。至于内存问题,您确定这里没有触发组合爆炸吗?您可以尝试将collect_mode of breadth_first添加到顶级聚合中吗?更多关于组合爆炸的信息,在这里:explosions.html

试试这个:

代码语言:javascript
复制
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "urlpath": "some_url_path.html"
        }
      }
    }
  },
  "aggs": {
    "agg_1": {
      "terms": {
        "size": 10,
        "order": {
          "sessions_number": "desc"
        },
        "field": "urlpath",
        "collect_mode": "breadth_first"
      },
      "aggs": {
        "sessions_number": {
          "cardinality": {
            "field": "session"
          }
        }
      }
    }
  }
}
票数 1
EN

Stack Overflow用户

发布于 2018-04-14 14:17:34

如果有嵌套文档,也需要过滤聚合。这允许在特定的子文档上进行聚合,而不是对所有项进行聚合。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43344058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档