在使用elasticsearch (5.3.0)时,我们在涉及几个嵌套聚合的查询中遇到内存不足问题。
我们从经验上发现,问题在于聚合是根据完整的索引计算的,而不是考虑到query块中指定的条件。后来,我们成功地运行了查询,将这些条件移动到一个filter聚合(参见文档)中,该聚合封装了所有原始的aggs。
为什么会有一个单独的语法呢?如果elasticsearch在填充存储桶时只考虑所有查询条件,岂不是更好吗?
如果我选择以这种方式将所有聚合查询包装在filter查询中,那么风险和/或限制是什么?逻辑上有什么不同吗?
注意:在我们的应用程序中,根本不关心文档评分。所有条件都有过滤文档的唯一目的,而不是对文档进行排序。我们确实根据文档计数或聚合度量来过滤存储桶。
编辑:有些人要求查询,如果他们帮助澄清情况,他们就在这里。请注意,这个问题是一般性的,而不是针对这一具体情况的。
{
"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"
}
}
}
}
}
}及之后:
{
"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子句,那么问题就不会产生了,而且对于过滤器而不是查询也是如此。这对我们来说是最令人惊讶的,因为应该只有一个桶,使任何订单变得琐碎。这使我相信,过滤不是在测试之前进行的,为此,我试图将所有的内容都封装在过滤聚合中。
发布于 2017-04-12 02:36:39
在第一个示例中,您实际上不是筛选数据,而是查询数据。这只会影响搜索结果的评分过程,而不影响聚合的过滤。
尽管ElasticSearch的最新版本已经结合了查询/筛选语法,但理解两者之间的区别仍然很重要。根据这里的文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html
查询上下文中使用的查询子句回答了“此文档与此查询子句的匹配程度如何?”除了决定文档是否匹配之外,查询子句还计算一个_score,表示文档相对于其他文档的匹配程度。 在筛选器上下文中,查询子句回答“此文档与此查询子句匹配吗?”答案是简单的“是”或“否”, - 没有计算分数。过滤器上下文主要用于过滤结构化数据。
构建第一个查询的更好方法是将过滤器包装在query.constant_score或query.bool中,如下所示:
{
"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
试试这个:
{
"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"
}
}
}
}
}
}发布于 2018-04-14 14:17:34
如果有嵌套文档,也需要过滤聚合。这允许在特定的子文档上进行聚合,而不是对所有项进行聚合。
https://stackoverflow.com/questions/43344058
复制相似问题