gpt4 book ai didi

elasticsearch - 在具有特定结果集的 Elasticsearch 中按多列分组

转载 作者:行者123 更新时间:2023-12-02 22:28:31 24 4
gpt4 key购买 nike

我是ES新手,并且有一些特定要求,我的文档如下所示

{
"_index" : "bidder_server_stats",
"_type" : "doc",
"_id" : "_NTrHGQBv0YTjfMi0Ord",
"_score" : 1.0,
"_source" : {
"avg_price" : 5.8,
"bc" : "2513",
"log_dt_st" : "2018-06-08T06:36:16.073Z",
"nid" : "1",
"cc" : "880",
"host" : "ip-172-31-18-62.ec2.internal",
"country" : "us"
}
},
{
"_index" : "bidder_server_stats",
"_type" : "doc",
"_id" : "_NTrHGQBv0YTjfMi0Ord",
"_score" : 1.0,
"_source" : {
"avg_price" : 10,
"bc" : "2514",
"log_dt_st" : "2018-06-08T06:36:16.073Z",
"nid" : "1",
"cc" : "880",
"host" : "ip-172-31-18-62.ec2.internal",
"country" : "us"
}
},
{
"_index" : "bidder_server_stats",
"_type" : "doc",
"_id" : "_NTrHGQBv0YTjfMi0Ord",
"_score" : 1.0,
"_source" : {
"avg_price" : 11,
"bc" : "2513",
"log_dt_st" : "2018-06-08T06:36:16.073Z",
"nid" : "1",
"cc" : "880",
"host" : "ip-172-31-18-62.ec2.internal",
"country" : "us"
}
}

现在我需要使用以下查询的结果
select bc,log_dt_st,sum(avg_price) from table group by bc,log_dt_st.

我们如何在Elasticsearch中做到这一点。我只想要结果集中的这三列(即_source)。

请帮忙

最佳答案

您可以使用sub-aggregations来实现。从ES 6.1开始, composite 聚合也可以派上用场(尽管仍处于试验阶段)。
查询可能如下所示:

POST bidder_server_stats/doc/_search
{
"size": 0,
"aggs": {
"by bc": {
"terms": {
"field": "bc"
},
"aggs": {
"by log_dt_st": {
"terms": {
"field": "log_dt_st"
},
"aggs": {
"sum(avg_price)": {
"sum": {
"field": "avg_price"
}
}
}
}
}
}
}
}
响应看起来像这样:
{
...
"aggregations": {
"by bc": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "2513",
"doc_count": 2,
"by log_dt_st": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 1528439776073,
"key_as_string": "2018-06-08T06:36:16.073Z",
"doc_count": 2,
"sum(avg_price)": {
"value": 16.800000190734863
}
}
]
}
},
{
"key": "2514",
"doc_count": 1,
"by log_dt_st": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 1528439776073,
"key_as_string": "2018-06-08T06:36:16.073Z",
"doc_count": 1,
"sum(avg_price)": {
"value": 10
}
}
]
}
}
]
}
}
}
片刻考虑:
  • bc应该具有keyword类型(以便能够对其进行 terms 聚合)
  • terms聚合默认仅返回前10个存储桶;您可能对此聚合
  • sizesort选项感兴趣

    更新:响应评论中的问题,因为它将改善答案。
    我们可以在结果集中添加更多字段而不将其添加到汇总中吗?
    不,不是直接。就像在SQL GROUP BY中一样,返回的所有字段都应该是 GROUP BY的一部分或聚合函数。
    除了聚合,实际上很少有其他选项可以获取更多数据:
  • 搜索结果本身(hits部分);
  • top_hits 聚合,它允许给定存储桶具有一些最相关的文档。

  • 我们可以添加多少个子聚合?
    我找不到任何相关的文档或配置设置来确定答案。但是, Dynamic index settings中有 index.max_docvalue_fields_search设置默认为 100。由于聚合使用 doc_values ,我想说大约100个存储桶聚合是一个合理的上限。
    我相信这里的限制是您的Elasticsearch集群的实际性能。
    我们可以将所有结果字段都放在同一个存储桶中吗?
    可以做到,但可能没有效率。您可以使用 script聚合的 terms 模式。查询可能如下所示:
    POST bidder_server_stats/doc/_search
    {
    "size": 0,
    "aggs": {
    "via script": {
    "terms": {
    "script": {
    "source": "doc['bc'].value +':::'+ doc['log_dt_st'].value ",
    "lang": "painless"
    }
    },
    "aggs": {
    "sum(avg_price)": {
    "sum": {
    "field": "avg_price"
    }
    }
    }
    }
    }
    }
    结果将如下所示:
    {
    ...
    "aggregations": {
    "via script": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [
    {
    "key": "2513:::2018-06-08T06:36:16.073Z",
    "doc_count": 2,
    "sum(avg_price)": {
    "value": 16.800000190734863
    }
    },
    {
    "key": "2514:::2018-06-08T06:36:16.073Z",
    "doc_count": 1,
    "sum(avg_price)": {
    "value": 10
    }
    }
    ]
    }
    }
    }
    为了执行此聚合,Elasticsearch将必须为每个与查询匹配的文档计算存储桶值,这相当于SQL中的完整扫描。相反,聚合更像是索引查找,因为它们使用 doc_values数据表示形式,该数据结构使这些查找有效。
    在某些情况下, script存储桶可以是一种解决方案,但是它们的范围非常有限。如果您对基于 script的解决方案感兴趣,还可以考虑使用 scripted metric aggregation
    希望有帮助!
    更新:从ES 6.1开始,可以使用 composite聚合
    在Elasticsearch 6.1中,添加了 composite 聚合。从6.3开始,它仍标记为 experimental(因此API可能会更改,或者将来可能会完全删除此功能)。
    这种情况下的查询如下所示:
    POST bidder_server_stats/doc/_search
    {
    "size": 0,
    "aggs": {
    "my composite": {
    "composite": {
    "sources": [
    {
    "bc": {
    "terms": {
    "field": "bc"
    }
    }
    },
    {
    "log_dt_st": {
    "terms": {
    "field": "log_dt_st"
    }
    }
    }
    ]
    },
    "aggs": {
    "sum(avg_price)": {
    "sum": {
    "field": "avg_price"
    }
    }
    }
    }
    }
    }
    以及响应:
    {
    "aggregations": {
    "my composite": {
    "after_key": {
    "bc": "2514",
    "log_dt_st": 1528439776073
    },
    "buckets": [
    {
    "key": {
    "bc": "2513",
    "log_dt_st": 1528439776073
    },
    "doc_count": 2,
    "sum(avg_price)": {
    "value": 16.800000190734863
    }
    },
    {
    "key": {
    "bc": "2514",
    "log_dt_st": 1528439776073
    },
    "doc_count": 1,
    "sum(avg_price)": {
    "value": 10
    }
    }
    ]
    }
    }
    }

    关于elasticsearch - 在具有特定结果集的 Elasticsearch 中按多列分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51264325/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com