对于我对ElasticSearch的一些查询,我想要回复三条信息:
使用默认术语facet或现在通过术语聚合方法可以轻松确定第一个点。
所以我的问题实际上是关于第三点。
在ElasticSearch 1.x之前,即在切换到'聚合之前范式,我可以使用“全球”这个术语的一个方面。选项设置为true
和QueryFilter
,以获取QueryFilter
指定的文档集中出现的确切字词的文档频率('全局计数')。
起初我以为我可以使用global aggregation
做同样的事情,但似乎我无法做到。原因是 - 如果我理解正确 - 原始facet
机制以术语为中心,而聚合桶由属于每个桶的文档集定义。
即使用global
指定term facet
的{{1}}选项首先确定过滤器命中的术语,然后计算构面值。由于方面是QueryFilter
,我会收到文件计数。
通过汇总,它有所不同。 global
聚合只能用作顶级聚合,导致聚合忽略当前查询结果并计算聚合 - 例如a global
- 索引中的所有文档。所以对我而言,这太过分了,因为我想将返回的术语('存储桶')限制为文档结果集中的术语。但是如果我使用带子项聚合的过滤子聚合,我会将术语桶再次限制为过滤器,因此不会检索文档频率而是检索正常的面数。原因是铲斗是在过滤器之后确定的,所以它们太小了#34;但是我不想要限制存储桶大小,我想将存储桶限制为查询结果集中的条件。
如何使用聚合在查询结果集中获取这些术语的文档频率(因为不推荐使用facet并将其删除)?
谢谢你的时间!
编辑:以下是我尝试实现所需行为的示例。 我将定义两个聚合:
它们的顶部都有一个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
。我们可以很容易地看到这些术语分别出现在结果集155和40次中。现在请看第二个聚合fid6
。术语聚合在全局聚合的范围内,因此我们实际上可以分别看到文档频率1050和668。所以这部分看起来不错。当您进一步向下扫描术语桶列表时,会出现问题,即使用密钥global_agg_with_terms_and_filter
到fid10
的桶。虽然我们收到他们的文档频率,但我们也可以看到他们的fid12
为0.这是因为我们的查询中没有出现这些术语,我们也用于过滤子聚合。所以问题是对于所有术语(全局范围!),返回他们的文档频率和关于实际查询结果的面数。但我需要完全针对查询结果中出现的术语,即第一个聚合term_count
返回的确切术语。
也许有可能定义某种类型的过滤器来删除其子过滤器聚合global_agg_with_filter_and_terms
为零term_count
的所有桶?
答案 0 :(得分:1)
如果答案迟了,你好,很抱歉。
您应该查看Significant Terms聚合,就像聚合术语一样,它会为结果集中出现的每个术语返回一个存储桶,其中包含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
}
}
}
}