Appearance
指标定义
在语义层中定义计算和关键绩效指标(KPIs)
指标介绍
指标是基于语义模型中度量或维度的计算。它们代表关键业务绩效指标(KPIs)和其他常用计算,集中封装业务逻辑。
基本结构定义如下:
yaml
metrics:
- name: metric_name # 必需 - 指标的唯一标识符
expr: "SQL_expression" # 必需 - 定义计算的SQL表达式
description: "业务定义" # 必需 - 指标的清晰解释
args: # 可选 - 用于参数化指标
- name: parameter_name
type: parameter_type
description: "参数描述"
default: default_value # 可选指标 vs 度量
区分指标(metrics)与度量(measures)和维度(dimensions)很有帮助:
- 维度:用于分组或筛选的描述性属性(如国家、状态)
- 度量:表示对单列的直接可聚合计算,通常对应于原始数据字段(如SUM(amount)定义为名为total_amount的度量)
- 指标:定义更复杂的计算、业务逻辑或关键绩效指标(KPIs),通常组合多个度量、维度或涉及条件逻辑
指导原则:
- 如果需要简单的直接列聚合(如求和、计数、平均),定义为度量
- 如果需要定义特定的业务KPI、比率、涉及多个步骤或度量的计算,或参数化计算,定义为指标
定义基础指标
核心指标包含名称、计算表达式(expr)和描述。
| 字段 | 是否必需 | 描述 |
|---|---|---|
| name | 是 | 模型中指标的唯一名称 |
| expr | 是 | 定义指标计算的SQL表达式,可引用度量、维度和参数 |
| description | 是 | 指标的人类可读描述 |
| args | 否 | 参数化指标表达式的参数对象列表 |
编写表达式
expr字段使用与数据仓库兼容的SQL语法定义指标计算。
- 引用字段:可直接引用同一模型中定义的维度和度量
- 聚合函数:使用标准SQL聚合函数(SUM, AVG, COUNT等)
- 运算符:支持算术、逻辑和比较运算符
- 函数:可使用大多数标准SQL函数
示例:基础指标
yaml
metrics:
- name: total_revenue
expr: "SUM(orders.amount)"
description: >
通过汇总查询上下文中所有订单的'amount'计算总收入。代表毛收入。
- name: order_count
expr: "COUNT(DISTINCT orders.order_id)"
description: >
基于'order_id'的不同计数,查询上下文中包含的唯一订单总数。高级指标类型
除了基础计算,还可以创建更动态和互连的指标。
参数化指标
创建接受用户查询时输入的灵活指标。使用双花括号引用参数。
示例:参数化指标
yaml
metrics:
- name: revenue_in_last_n_days
description: 计算用户指定或默认为30天的最近N天的总收入。
expr: "SUM(CASE WHEN orders.order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL {{days}} DAY) THEN orders.amount ELSE 0 END)"
args:
- name: days
type: number
description: 收入计算中包含的天数。
default: 30跨模型指标
使用点符号(related_model_name.field_name)引用相关模型中的字段。这需要在相关模型之间定义关系。
示例:跨模型指标
yaml
metrics:
- name: revenue_per_customer
description: >
订单查询上下文中每个唯一客户的平均收入。需要通过'customer'关系将'orders'模型与'customers'模型连接。
expr: "SUM(orders.amount) / NULLIF(COUNT(DISTINCT customer.id), 0)"复合指标
yml
- name: total_ship_amount # 基础指标
label: 发货总金额
description: >
发货金额、发货总金额、出库金额、出库总金额。
expr: SUM(ship_amount)
type: double
format: '¥#,##0.00'
- name: total_refund_amount # 基础指标
label: 退货总金额
description: >
退货总金额、退货金额、退货额。
expr: SUM(refund_amount)
type: double
format: '¥#,##0.00'
- name: total_income_amount # 复合指标
label: 收入
description: >
退后GMV、收入、总收入、收入金额、收入总金额、销售额。
expr: "{{ metric('total_ship_amount') }} - {{ metric('total_refund_amount') }}"
type: double
format: '¥#,##0.00'最佳实践与注意事项
遵循这些指南创建健壮、可理解和可维护的指标。
通用最佳实践
- 业务导向:定义代表有意义业务KPI的指标
- 清晰命名与描述:使用一致、描述性名称并提供清晰描述
- 利用现有组件:通过引用模型中现有度量和维度构建指标
- 记录依赖关系:明确说明指标对参数或相关模型数据的依赖
表达式最佳实践
- 类型一致性:确保表达式解析为适合聚合的适当数据类型
- 使用表前缀:引用相关模型字段时始终使用表限定名称
- SQL约定:
- 用括号包裹复杂表达式确保正确运算符优先级
- 使用NULLIF处理除零错误
- 注意空值处理
- 避免循环引用
良好表达式示例(参数化):
yaml
metrics:
- name: avg_order_value_by_date
description: 指定日期范围内订单的平均订单价值。
expr: "SUM(CASE WHEN orders.created_at BETWEEN '{{start_date}}' AND '{{end_date}}' THEN orders.amount ELSE 0 END) / NULLIF(COUNT(CASE WHEN orders.created_at BETWEEN '{{start_date}}' AND '{{end_date}}' THEN orders.id ELSE NULL END), 0)"
args:
- name: start_date
type: date
description: 开始日期(YYYY-MM-DD)。
- name: end_date
type: date
description: 结束日期(YYYY-MM-DD)。参数最佳实践
- 显式类型:始终为每个参数定义类型
- 参数字段:确保args列表中的每个参数包含必需字段
- 默认值:为可选参数提供默认值
- 清晰文档:为每个参数提供有意义的描述
- 占位符:使用双花括号引用参数
综合示例
以下是订单模型上下文中的示例,包含各种指标类型和实践:
yaml
name: orders
description: >
表示单个客户订单交易。包含每个订单的详细信息,
包括标识符、客户链接、时间、状态和财务价值。
dimensions:
- name: order_id
description: 订单交易的唯一标识符。
type: string
- name: order_date
description: 订单下单日期。
type: date
- name: status
description: 订单的当前履行或支付状态。
type: string
- name: customer_id
description: 将订单链接到客户的标识符。
type: string
measures:
- name: amount
description: 订单的总货币价值(如美元)。
type: number
- name: item_count
description: 订单中包含的不同商品数量。
type: integer
metrics:
# 基础指标
- name: total_revenue
description: 通过汇总查询上下文中所有订单的'amount'计算总收入。
expr: "SUM(orders.amount)"
- name: average_order_value
description: 计算查询结果中所有订单的平均'amount'。
expr: "AVG(orders.amount)"
# 参数化指标
- name: revenue_by_period
description: 最近N天内下单的订单总收入。
expr: "SUM(CASE WHEN orders.order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL {{days}} DAY) THEN orders.amount ELSE 0 END)"
args:
- name: days
type: number
description: 计算中回溯的天数(整数)。
default: 30
# 跨模型指标
- name: revenue_per_customer
description: 订单查询上下文中每个唯一客户的平均收入。
expr: "SUM(orders.amount) / NULLIF(COUNT(DISTINCT customer.id), 0)"
# 更复杂的参数化指标
- name: revenue_growth_vs_prior_periods
description: >
计算与N个周期前相比的总收入百分比增长。
注意:此计算依赖于`LAG`窗口函数。
expr: "(SUM(orders.amount) - LAG(SUM(orders.amount), {{periods}}) OVER (ORDER BY orders.order_date)) / NULLIF(LAG(SUM(orders.amount), {{periods}}) OVER (ORDER BY orders.order_date), 0)"
args:
- name: periods
type: number
description: 比较的先前周期数(如1表示紧接的前一个周期)。
default: 1