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

Hasura如何按列中相同值分组并统计数量?

在Hasura中实现按列值分组统计数量

需求说明

需要对analytics表的visitor_id、type、os等列按值分组并统计数量,最终得到类似如下结构的统计结果:

{
    "user_id": "user_2Jy9jmL8OIpyb1DpTGYrrtjS77P",
    "visitor_id": {
        "null": 41,
        "user_2JzAMaOW8j01rpsl98McXwBlCkv": 30
    },
    "type": {
        "visit": 71,
        "shares": 0,
        "clicks": 0
    },
    "os": {
        "Windows 10": 28,
        "iOS 13.2.3": 36,
        "null": 7
    },
    "device": { 
        "Desktop": 60,
        "Mobile": 10,
        "null": 7
    },
    "country": { 
        "Japan": 60,
        "null": 7
    },
    "browser": {
        "Chrome": 28,
        "Mobile Safari": 36,
        "null": 7
    }
}

实现方法

Hasura支持通过group_by和聚合函数实现分组统计,需要针对每个目标列单独编写分组查询,再将结果转换为目标结构。

1. 编写分组统计的GraphQL查询

query getAnalyticsGrouped($from: timestamptz, $to: timestamptz, $user_id: String) {
  # 获取当前用户ID(也可直接使用传入的$user_id参数)
  user_info: analytics_aggregate(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}) {
    nodes {
      user_id
    }
  }

  # visitor_id 分组统计
  visitor_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [visitor_id]) {
    visitor_id
    aggregate {
      count
    }
  }

  # type 分组统计
  type_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [type]) {
    type
    aggregate {
      count
    }
  }

  # os 分组统计
  os_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [os]) {
    os
    aggregate {
      count
    }
  }

  # device 分组统计
  device_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [device]) {
    device
    aggregate {
      count
    }
  }

  # country 分组统计
  country_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [country]) {
    country
    aggregate {
      count
    }
  }

  # browser 分组统计
  browser_stats: analytics_group_by(where: { created_at: {_gte: $from, _lte: $to}, user_id: {_eq: $user_id}}, group_by: [browser]) {
    browser
    aggregate {
      count
    }
  }
}

2. 转换查询结果为目标结构

Hasura返回的是分组列表格式,需要通过前端代码转换为键值对结构。以JavaScript为例:

// 假设queryResult是Hasura返回的查询结果
const formatAnalyticsStats = (queryResult, userId) => {
  // 通用转换函数:将分组列表转为键值对,处理null值
  const convertToKeyValue = (stats) => {
    return stats.reduce((acc, item) => {
      const keyField = Object.keys(item).find(k => k !== 'aggregate');
      const value = item[keyField] ?? 'null';
      acc[value] = item.aggregate.count;
      return acc;
    }, {});
  };

  return {
    user_id: queryResult.user_info.nodes[0]?.user_id || userId,
    visitor_id: convertToKeyValue(queryResult.visitor_stats),
    // type字段需要补全预设的0值项
    type: {
      visit: 0,
      shares: 0,
      clicks: 0,
      ...convertToKeyValue(queryResult.type_stats)
    },
    os: convertToKeyValue(queryResult.os_stats),
    device: convertToKeyValue(queryResult.device_stats),
    country: convertToKeyValue(queryResult.country_stats),
    browser: convertToKeyValue(queryResult.browser_stats)
  };
};

关键说明

  • analytics_group_by是Hasura自动生成的分组查询字段,指定group_by参数为要统计的列,通过aggregate.count获取该分组的记录数。
  • 对于需要展示0值的列(如type中的shares、clicks),因为Hasura只会返回数据库中存在的分组值,所以需要在转换时手动补全预设项。
  • 数据库中的null值会被Hasura作为独立分组返回,转换时可将其映射为字符串"null"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:25:23