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

如何在go-redis聚合函数中按时间范围过滤计算duration总和

在go-redis中基于时间范围筛选并聚合Redis数据

要实现按时间范围筛选条目后聚合duration字段的总和,你需要利用RedisSearch的范围查询语法,在FTAggregateOptions中添加筛选条件。以下是具体实现方案:

核心思路

RedisSearch支持通过@字段名:[最小值 最大值]的语法筛选数值/日期类型的字段,优先使用全局过滤条件(先筛数据再聚合,性能更优),若需分组内过滤再单独配置分组的Filter。

修改后的代码示例

假设你的时间戳字段名为timestamp(存储为Unix时间戳),以下是完整实现:

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
)

func getFilteredDurationSum(ctx context.Context, rdb *redis.Client) (float64, error) {
    // 定义目标时间范围(替换为你的实际时间戳)
    startTs := 1717000000
    endTs := 1717864000

    aggOpts := redis.FTAggregateOptions{
        // 全局过滤:只保留timestamp在[startTs, endTs]范围内的条目
        Filter: fmt.Sprintf("@timestamp:[%d %d]", startTs, endTs),
        GroupBy: []redis.FTAggregateGroupBy{
            {
                Fields: []interface{}{"@ID"},
                Reduce: []redis.FTAggregateReducer{
                    {
                        Reducer: redis.SearchSum,
                        Args:    []interface{}{"@duration"},
                        As:      "sum_duration",
                    },
                },
            },
        },
    }

    // 执行聚合查询(注意替换*为你的实际索引名称)
    result, err := rdb.FTAggregateWithArgs(ctx, "*", &aggOpts).Result()
    if err != nil {
        return 0, err
    }

    // 计算所有分组的总和
    total := 0.0
    for _, row := range result {
        if sum, ok := row["sum_duration"].(float64); ok {
            total += sum
        }
    }
    return total, nil
}

额外说明

  1. 时间格式适配:如果你的时间戳是ISO字符串(如2024-06-01T00:00:00),且字段已被索引为日期类型,可直接用字符串范围查询:
    Filter: `@timestamp:["2024-06-01" "2024-06-10"]`
    
  2. 范围类型调整:RedisSearch支持开区间(用())和混合区间,比如@timestamp:[(1717000000 1717864000]表示大于startTs且小于等于endTs。
  3. 无分组聚合:如果不需要按ID分组,仅需全局求和,可去掉GroupBy配置,改用顶层Reduce:
    aggOpts := redis.FTAggregateOptions{
        Filter: fmt.Sprintf("@timestamp:[%d %d]", startTs, endTs),
        Reduce: []redis.FTAggregateReducer{
            {
                Reducer: redis.SearchSum,
                Args:    []interface{}{"@duration"},
                As:      "total_sum",
            },
        },
    }
    // 解析结果时直接取第一个行的total_sum
    total := result[0]["total_sum"].(float64)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:03:12