You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch 7.16聚合查询如何添加关联database字段?

问题:聚合查询时同时获取table对应的database信息

我正在使用Python 3.6操作Elasticsearch 7.16,Elasticsearch中存储的数据如下:

{"owner": "john", "database": "postgres", "table": "sales_tab"},
{"owner": "hannah", "database": "mongodb", "table": "dept_tab"},
{"owner": "peter", "database": "mysql", "table": "new_tab"},
{"owner": "jim", "database": "postgres", "table": "cust_tab"},
{"owner": "lima", "database": "postgres", "table": "sales_tab"},
{"owner": "tory", "database": "oracle", "table": "store_tab"},
{"owner": "kane", "database": "mysql", "table": "trasit_tab"},
{"owner": "roma", "database": "mongodb", "table": "common_tab"},
{"owner": "ashley", "database": "mongodb", "table": "common_tab"},

执行以下聚合查询:

{
    "size": 0,
    "aggs": {
        "table_grouped": {
          "terms": {
            "field": "table",
            "size": 100000
          }
        }
      }
}

得到的结果仅包含distinct table值及对应文档数:

{... 'aggregations': {'table_grouped': {'doc_count_error_upper_bound': 0, 'sum_other_doc_count': 0, 
'buckets': [{'key': 'sales_tab', 'doc_count': 3}, {'key': 'dept_tab', 'doc_count': 1}, 
{'key': 'new_tab', 'doc_count': 1}, {'key': 'cust_tab', 'doc_count': 1}, 
{'key': 'store_tab', 'doc_count': 1}, {'key': 'trasit_tab', 'doc_count': 1}, 
{'key': 'common_tab', 'doc_count': 2}]}}}

但我需要在每个bucket中添加对应table所属的database字段,期望结果如下:

{... 'aggregations': {'table_grouped': {'doc_count_error_upper_bound': 0, 'sum_other_doc_count': 0, 
'buckets': [{'key': 'sales_tab', 'doc_count': 2, "database": "postgres"}, {'key': 'dept_tab', 
'doc_count': 1, "database": "mongodb"}, {'key': 'new_tab', 'doc_count': 1, 
"database": "mysql"}, {'key': 'cust_tab', 'doc_count': 1, "database": "postgres"}, 
{'key': 'store_tab', 'doc_count': 1, "database": "oracle"}, {'key': 'trasit_tab', 'doc_count': 1, "database": "mysql"}, 
{'key': 'common_tab', 'doc_count': 2, "database": "mongodb"}]}}}

即获取distinct table的同时,得到其对应的database信息,请问该如何实现?


解决方案

可以通过在terms聚合内部嵌套子聚合来获取对应的database信息,以下两种方案都能满足需求:

方案一:嵌套terms聚合(适合单个table对应唯一database的场景)

在按table分组的聚合下,添加一个按database分组的子聚合,限制返回数量为1,这样就能拿到每个table对应的database:

{
    "size": 0,
    "aggs": {
        "table_grouped": {
            "terms": {
                "field": "table",
                "size": 100000
            },
            "aggs": {
                "db_info": {
                    "terms": {
                        "field": "database",
                        "size": 1
                    }
                }
            }
        }
    }
}

结果处理

执行查询后,每个table的bucket里会包含db_info字段,从中提取第一个bucket的key就是对应的database。在Python中可以这样处理结果:

from elasticsearch import Elasticsearch

es = Elasticsearch(["your-es-host:port"])
response = es.search(index="your-index-name", body=上述查询语句)

# 处理聚合结果
processed_buckets = []
for bucket in response["aggregations"]["table_grouped"]["buckets"]:
    db = bucket["db_info"]["buckets"][0]["key"]
    processed_buckets.append({
        "key": bucket["key"],
        "doc_count": bucket["doc_count"],
        "database": db
    })

# 替换原buckets
response["aggregations"]["table_grouped"]["buckets"] = processed_buckets
print(response)

方案二:使用top_hits聚合(通用场景,支持单个table对应多个database的情况)

top_hits聚合会返回每个分组下的指定数量文档,这里取第一条文档的database字段即可:

{
    "size": 0,
    "aggs": {
        "table_grouped": {
            "terms": {
                "field": "table",
                "size": 100000
            },
            "aggs": {
                "db_info": {
                    "top_hits": {
                        "size": 1,
                        "_source": ["database"]
                    }
                }
            }
        }
    }
}

结果处理

在Python中提取database的方式如下:

processed_buckets = []
for bucket in response["aggregations"]["table_grouped"]["buckets"]:
    db = bucket["db_info"]["hits"]["hits"][0]["_source"]["database"]
    processed_buckets.append({
        "key": bucket["key"],
        "doc_count": bucket["doc_count"],
        "database": db
    })

response["aggregations"]["table_grouped"]["buckets"] = processed_buckets
print(response)

内容的提问来源于stack exchange,提问作者young_minds1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:24:31