对于我对ElasticSearch的一些查询,我想要返回三条信息:
第一个点很容易使用默认术语facet或现在的术语聚合方法来确定。所以我的问题是关于第三点。在ElasticSearch 1.x之前,即在切换到“聚合”范式之前,我可以使用一个术语facet,它将“全局”选项设置为true,并使用一个QueryFilter来获取QueryFilter指定的文档集中发生的确切术语的文档频率(“全局计数”)。起初,我以为我可以使用global aggregation做同样的事情,但似乎我做不到。原因是--如果我正确理解--原来的facet机制以术语为中心,而聚合桶是由属于每个桶的文档集定义的。例如,使用global指定term facet的QueryFilter选项,首先确定过滤器击中的术语,然后计算facet值。由于facet是global,所以我将接收文档计数。
有了聚合,就不一样了。global聚合只能用作顶级聚合,从而导致聚合忽略当前查询结果,并计算索引中所有文档上的聚合(例如terms aggregation )。因此,对我来说,这太多了,因为我希望将返回的术语(“桶”)限制在文档结果集中的术语上。但是,如果我使用带有术语子聚合的过滤器子聚合,我会再次将术语桶限制在过滤器上,这样就不会检索文档频率,而是正常的方面计数。原因是水桶是在过滤器后确定的,所以它们“太小”。但是我不想限制桶大小,我想将桶限制在查询结果集中的条件上。
如何使用聚合在查询结果集中获取这些术语的文档频率(因为不推荐使用方面并将其删除)?
耽误您时间,实在对不起!
编辑:下面是我如何尝试实现所需行为的一个示例。我将定义两个集合:
它们的顶部都有一个global聚合,因为它是它的唯一有效位置。然后,在第一个聚合中,我首先将结果过滤到原始查询,然后应用一个术语-子聚合。在第二个聚合中,我所做的基本相同,只是这里的过滤器聚合是术语聚合的子聚合。因此,类似的名称,只有聚合的顺序不同。
{
"query": {
"query_string": {
"query": "text: my query string"
}
},
"aggs": {
"global_agg_with_filter_and_terms": {
"global": {},
"aggs": {
"filter_agg": {
"filter": {
"query": {
"query_string": {
"query": "text: my query string"
}
}
},
"aggs": {
"terms_agg": {
"terms": {
"field": "facets"
}
}
}
}
}
},
"global_agg_with_terms_and_filter": {
"global": {},
"aggs": {
"document_frequency": {
"terms": {
"field": "facets"
},
"aggs": {
"term_count": {
"filter": {
"query": {
"query_string": {
"query": "text: my query string"
}
}
}
}
}
}
}
}
}
}响应:
{
"took": 18,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 221,
"max_score": 0.9839197,
"hits": <omitted>
},
"aggregations": {
"global_agg_with_filter_and_terms": {
"doc_count": 1978,
"filter_agg": {
"doc_count": 221,
"terms_agg": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "fid8",
"doc_count": 155
},
{
"key": "fid6",
"doc_count": 40
},
{
"key": "fid9",
"doc_count": 10
},
{
"key": "fid5",
"doc_count": 9
},
{
"key": "fid13",
"doc_count": 5
},
{
"key": "fid7",
"doc_count": 2
}
]
}
}
},
"global_agg_with_terms_and_filter": {
"doc_count": 1978,
"document_frequency": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "fid8",
"doc_count": 1050,
"term_count": {
"doc_count": 155
}
},
{
"key": "fid6",
"doc_count": 668,
"term_count": {
"doc_count": 40
}
},
{
"key": "fid9",
"doc_count": 67,
"term_count": {
"doc_count": 10
}
},
{
"key": "fid5",
"doc_count": 65,
"term_count": {
"doc_count": 9
}
},
{
"key": "fid7",
"doc_count": 63,
"term_count": {
"doc_count": 2
}
},
{
"key": "fid13",
"doc_count": 55,
"term_count": {
"doc_count": 5
}
},
{
"key": "fid10",
"doc_count": 11,
"term_count": {
"doc_count": 0
}
},
{
"key": "fid11",
"doc_count": 9,
"term_count": {
"doc_count": 0
}
},
{
"key": "fid12",
"doc_count": 5,
"term_count": {
"doc_count": 0
}
}
]
}
}
}
}首先,请查看两个聚合的前两个返回的术语桶,其中键为fid8和fid6。我们可以很容易地看到,这些术语在结果集中分别出现了155次和40次。现在请看第二个聚合,global_agg_with_terms_and_filter。术语-聚合在全局聚合的范围内,因此这里我们可以看到文档频率分别为1050和668。所以这部分看起来不错。当您将术语桶的列表进一步向下扫描到带有键fid10到fid12的存储桶时,就会出现问题。当我们接收到他们的文档频率时,我们也可以看到他们的term_count是0。这是因为这些术语没有出现在我们的查询中,我们也用于过滤器子聚合。所以问题是,对于所有术语(全球范围!)返回它们的文档频率和相对于实际查询结果的方面计数。但是,我需要对查询结果中发生的术语,即第一个聚合global_agg_with_filter_and_terms返回的确切术语,进行精确的处理。
也许有可能定义某种过滤器来移除所有的桶,在这些桶中,它们的子过滤器聚合term_count有一个零doc_count。
发布于 2015-06-17 15:30:09
你好,如果答复迟到了,很抱歉。
您应该了解一下重要条款聚合,因为与术语聚合一样,它在结果集中为每个条目返回一个桶,其中包含通过doc_count可用的事件数,但您也可以通过bg_count获得背景集中出现的次数。这意味着它只为出现在查询结果集文档中的术语创建桶。
默认背景集包含查询范围中的所有文档,但可以使用background_filter筛选到任何您想要的子集。
您可以通过组合几个指标,使用脚本编写的桶评分函数按照您想要的方式对桶进行排序:
_subset_freq:术语出现在结果集中的文档数,_superset_freq:术语出现在背景集中的文档数,_subset_size:结果集中的文档数,_superset_size:背景集中的文档数。请求:
{
"query": {
"query_string": {
"query": "text: my query string"
}
},
"aggs": {
"terms": {
"significant_terms": {
"script": "_subset_freq",
"size": 100
}
}
}
}https://stackoverflow.com/questions/26782234
复制相似问题