构建指标平台(语义层)的指标数据查询 API 请求。当用户需要查询指标数据、构造指标查询API请求体、使用同环比/占比/排名/时间限定等快速计算、定义临时指标、设置维度筛选过滤条件时,必须使用此 Skill。 触发场景包括但不限于:用户提到"查询指标"、"指标API"、"指标数据"、"语义层查询"、"metric...
指标数据查询 API Skill是一项面向实际任务的技能,主要用于根据用户自然语言描述, 先通过 Gateway 检索指标和维度 ,再生成语义接口 /semantic/api/v1.1/metrics/query 的请求体 JSON;Gateway 搜索 API(Step 1 — 检索指标和维度);
实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;
涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
根据用户自然语言描述,先通过 Gateway 检索指标和维度,再生成语义接口 /semantic/api/v1.1/metrics/query 的请求体 JSON。
搜索指标: GET https://gateway.can.aloudata.com/api/metrics/search?keyword={关键词,可逗号分隔}&pageSize={数量}
单指标维度: GET https://gateway.can.aloudata.com/api/metrics/{metricName}/dimensions?keyword={可选过滤词}
批量指标维度: GET https://gateway.can.aloudata.com/api/metrics/dimensions?metricNames={指标1,指标2}&keyword={可选过滤词}
指标列表: GET https://gateway.can.aloudata.com/api/metrics/list?pageNumber={页码}&pageSize={数量}
指标目录: GET https://gateway.can.aloudata.com/api/metrics/categories
目录下指标: GET https://gateway.can.aloudata.com/api/metrics/categories/{categoryId}?pageSize={数量}
认证方式:所有请求必须携带 API Key,通过请求头 X-API-Key 传递(也可通过 ?apikey= 查询参数传递)。返回格式为纯文本,非 JSON。
⚠️ 调用 Gateway 的两条铁律:
-H "X-API-Key: $CAN_API_KEY",$CAN_API_KEY 从环境变量读取(用户需在 ~/.openclaw/.env 中配置 CAN_API_KEY=cgk-xxxxxxxx),未携带或无效 Key 将返回 401--data-urlencode + -G 让 curl 自动编码,禁止中文直接拼入 URL示例:
# 搜索单个指标 curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=5" --data-urlencode "keyword=客单价" -G # 批量搜索多个指标(逗号分隔) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=3" --data-urlencode "keyword=客单价,销售额" -G # 单指标维度查询(路径参数直接用 metricName) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" # 按关键词过滤维度(只返回匹配的维度,keyword 支持逗号分隔多关键词,匹配任一即返回) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" --data-urlencode "keyword=渠道" -G # 多关键词过滤维度(逗号分隔,匹配维度名/展示名/描述/维度值样本中任一关键词的维度都会返回) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" --data-urlencode "keyword=渠道,地区,品牌" -G # 批量指标维度查询(自动计算维度交集,keyword 同样支持多关键词) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/dimensions?metricNames=AOV,retail_amt" --data-urlencode "keyword=渠道" -G # 指标目录(查看所有类目层级) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/categories" # 查看指定目录下的指标 curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/categories/{categoryId}?pageSize=20" # 指标列表(分页浏览全部指标) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/list?pageNumber=1&pageSize=50"
接口: POST https://gateway.can.aloudata.com/api/metrics/query
认证方式:同上,必须携带 API Key 认证头。
示例(⚠️ 因为 timeConstraint 含单引号
['metric_time'],必须用 heredoc 传 JSON body,禁止用-d '...'单引号包裹):curl -X POST "https://gateway.can.aloudata.com/api/metrics/query" -H "X-API-Key: $CAN_API_KEY" -H "Content-Type: application/json" -d @- <<'EOF' {"metrics": ["AOV"], "timeConstraint": "['metric_time__day']= DATEADD(DateTrunc(NOW(), "DAY"), -1, "DAY")"} EOF
构建 JSON 前,先逐条过一遍:
铁律 1 — 相对时间必须用 NOW(),禁止硬编码日期(包括 timeConstraint 和 period 锚定)
"上月""上周""本年""昨天""近N天""去年""本季""上季" 等相对时间 → 必须 NOW()。
DATEADD(DateTrunc(NOW(), "MONTH"), -1, "MONTH")DATEADD(DateTrunc('2026-03-05', "MONTH"), -1, "MONTH")"2025-04-01"⚠️ 特别注意:period 锚定的 timeConstraint 也必须用 NOW()
当使用 metricDefinitions + period 时,timeConstraint 作为 period 的锚定基准。如果用户说的是"本年至今""本月至今""近30天"等相对时间,锚定日期必须用 DATEADD(DateTrunc(NOW(), "DAY"), -1, "DAY") 表示"昨天",绝不可将当前日期(如 2026-03-06)直接写入 timeConstraint。
"timeConstraint": "['metric_time__day']= DATEADD(DateTrunc(NOW(), "DAY"), -1, "DAY")""timeConstraint": "['metric_time__day']= "2026-03-06""(硬编码当前日期)"timeConstraint": "['metric_time__day']= "2026-03-05""(硬编码昨天日期)铁律 2 — metricDefinitions 中每个 key 必须同时在 metrics 数组中(包括辅助指标)
定义了就必须注册。自检:数 metricDefinitions 的 key → 逐个确认在 metrics 中存在。
⚠️ 特别注意"辅助指标": 即使某个临时指标仅作为 expr 的中间计算变量(如 "total": { "refMetric": "metric_A", "specifyDimension": ... } 被 "ratio": { "expr": "[val]/[total]" } 引用),该辅助指标也必须出现在 metrics 数组中。API 不会自动推断依赖关系——metricDefinitions 中的每个 key 无论是最终输出还是中间计算,都需要在 metrics 中显式注册。
"metrics": ["ratio"] + "metricDefinitions": { "total": {...}, "ratio": { "expr": "[val]/[total]" } }(total 未注册)"metrics": ["total", "ratio"] + "metricDefinitions": { "total": {...}, "ratio": { "expr": "[val]/[total]" } }铁律 3 — 占比/排名 + filters = 分母/范围被缩小 → 结果恒 100%/恒为 1 要"某个值在全局中的占比/排名" → 用 resultFilters 做展示筛选,不用 filters。
⚠️ 特别注意"渠道内占比/排名"场景: 当用户问"Wholesale 渠道的渠道内占比/排名"时,含义是 Wholesale 在所有渠道中的占比/排名。此时:
first_channel),让所有渠道参与占比/排名计算resultFilters 仅展示 Wholesale 的行"filters": ["[first_channel]= "Wholesale""] → 只剩 Wholesale 自己,占比恒 100%、排名恒 1"resultFilters": ["[first_channel]= "Wholesale""] → 分母包含所有渠道铁律 4 — "同比"默认 = yoy;带粒度前缀时按前缀选择
yoymom(与上月同期比)wow(与上周同期比)qoq(与上季同期比)铁律 5 — 一个指标只能做一次快速计算,不可链式叠加 需要多步(如先算环比再排名)→ 用 metricDefinitions 分步。
retail_amt__sameperiod__mom__growth__rank__desc__first_channel(链式:环比 + 排名)retail_amt__sameperiod__yoy__growth__rankDense__desc__first_channel(链式:同比 + 排名)"metrics": ["mom_growth", "mom_growth__rankDense__desc__first_channel"],
"metricDefinitions": {
"mom_growth": {
"refMetric": "retail_amt",
"indirections": ["sameperiod__mom__growth"]
}
}
典型场景——"各渠道增速前N的品牌": 这类需求必须分步:第1步用 metricDefinitions 定义环比增速临时指标;第2步对临时指标做渠道内排名。
铁律 6 — MetricMatches 只能在 metricDefinitions 的 filters 中使用,禁止放在顶层 filters MetricMatches 是"基于指标值筛选维度值"的高级功能,必须包裹在临时指标定义(metricDefinitions)的 filters 中。
"metricDefinitions": { "temp": { "refMetric": "buyer_cnt", "filters": ["MetricMatches([vip_code], [retail_amt] >= 10000)"] } }"filters": ["MetricMatches([vip_code], [retail_amt] >= 10000)"](顶层 filters 不支持 MetricMatches)铁律 7 — 派生指标的 metric_time 粒度限制必须遵守
候选指标中标注"metric_time维度仅支持日粒度"的派生指标(如 sales_yoy、retail_amt_ytd 等),只能在 timeConstraint 锚定到天粒度时使用(如 ['metric_time__day']= ...)。当 timeConstraint 为周/月/季/年粒度时,禁止使用这些日粒度限制的派生指标,必须改用原子指标 + 快速计算语法。
retail_amt__sameperiod__yoy__growth(原子指标+快速计算)sales_yoy(日粒度派生指标 + 月级 timeConstraint = 不兼容)铁律 8 — "月变化趋势"中的占比/排名范围维度必须是 metric_time__month
当查询涉及"XX在YY内排名/占比的月变化趋势"时,范围维度必须是 metric_time__month(每月内独立计算排名/占比),而非实体维度或留空。
retail_amt__proportion__metric_time__month(每月内各渠道占比)retail_amt__rank__desc__metric_time__month(每月内各渠道排名)retail_amt__proportion__(全局占比,无月内分组 → 排名/占比跨月混淆)retail_amt__proportion__first_channel(每渠道内占比 → 恒100%)铁律 9 — 上下文不足时必须拒绝生成查询,返回空 JSON {},禁止虚构指标或忽视维度兼容性
在生成 JSON 前,必须执行以下三项上下文充分性检查。任何一项不通过,必须拒绝生成查询,在 buildReason 中说明缺失原因,并返回空 JSON {}。
{}核心原则: 宁可在 buildReason 中诚实说明"候选指标/维度不足以回答此问题",也不要为了"产出内容"而硬凑一个错误的查询。错误的查询比没有查询更有害——它会返回误导性数据。
⚠️ 非查询意图判断: 如果用户消息不包含任何数据查询意图(如"你好""谢谢""当前日期是XX"等对话性消息),则不应生成查询请求体。此时应返回空 JSON {} 或在 buildReason 中说明"用户消息不含查询意图"。切勿为了"产出内容"而生成一个空 metrics 或无意义的请求体。
在写任何 JSON 之前,先把用户的问题拆解为四个维度:
| 维度 | 问自己 | 示例 |
|---|---|---|
| 看什么(指标) | 用户要看的业务量是什么?有没有修饰语(日均、不含税…)? | "销售额""日均订单数""客单价(不含税)" |
| 怎么看(分析方式) | 直接看值?还是要对比/占比/排名/趋势? | "同比增长率""占比""排名前5""月趋势" |
| 看谁的(维度 & 筛选) | 按什么维度拆分?筛选哪些范围? | "各品牌""某渠道""某地区" |
| 看哪段时间(时间) | 时间范围是什么?是否涉及时间对比? | "上月""近7天""某月 vs 另一月" |
以下 9 条规则解决的是"怎么理解用户的中文",而非"怎么写 JSON"。
规则 A — "总和" vs "分别"
| 用户说 | 含义 | dimensions 处理 |
|---|---|---|
| "A 和 B 的某指标分别是多少" | 按 A、B 分组展示 | 保留维度 |
| "A 和 B 的某指标总和" | A+B 合并为一个数字 | 不放该维度 |
| "A 和 B 的某指标"(无修饰) | 歧义,默认"分别" | 保留维度 |
规则 B — 修饰语的作用域
"日均/月均/平均" 修饰的是紧跟其后的所有并列项:
规则 C — "占比" 的两种含义
| 用户说 | 含义 | 实现方式 |
|---|---|---|
| "某指标占比"(如"销售额占比") | 值占比(金额/数量占比) | 直接用 proportion 快速计算 |
| "某实体占比"(如"款色占比""客户占比""门店数占比") | 数量占比 | 需要先用计数指标统计数量,再对计数指标做 proportion |
判断标准:如果"占比"前面是一个实体类型(款色、客户、门店、SKU)而非指标(销售额、订单数),则是数量占比。
规则 D — "XX均" 的聚合维度
"XX均"中的"XX"就是聚合维度,不要替换为其他维度。在候选维度表中找到"XX"对应的维度名称,用 multi_level_agg__avg,{该维度名} 实现。
示例:
multi_level_agg__avg,{门店维度}multi_level_agg__avg,{客户维度},或用 expr: [总指标]/[计数指标]规则 E — "同比" vs "环比"
| 用户说 | 映射 | 说明 |
|---|---|---|
| "同比"(无限定) | yoy | 默认=年同比,详见铁律 4 |
| "年同比" | yoy | |
| "月同比" | mom | 与上月同期比 |
| "周同比" | wow | 与上周同期比 |
| "季同比" | qoq | 与上季同期比 |
| "环比" | 根据时间粒度选:日→dod,周→wow,月→mom,季→qoq | ❌ 不可映射为 yoy |
规则 F — "对比去年末" ≠ "年同比"
| 用户说 | 含义 | 实现方式 |
|---|---|---|
| "同比""年同比" | 与去年同期对比 | __sameperiod__yoy__growth |
| "与去年末相比" | 与去年12月/去年最后一天对比 | metricDefinitions + period 定位去年末(如 SPECIFY_DATE end day of -1 year) |
| "与上月末相比" | 与上月最后一天对比 | __sameperiod__moeom__growth(需 day 粒度) |
规则 G — "趋势" ≠ 同环比
"趋势"/"变化趋势" = 按时间展开看值的变化,只需指标 + 时间维度。除非用户明确提到"同比""环比""增长率",否则不要额外添加同环比指标。
规则 H — "差异/差距/对比" ≠ 同环比
"各XX之间的差异""A和B的差距" = 直接查出各自的值让用户比较,不是同比/环比。只有用户明确说"同比""环比""增长率"时才加同环比计算。
规则 I — 简单优先
如果用户问题可以用简单查询(指标 + 维度 + 时间)回答,就不要添加不必要的 metricDefinitions、同环比、占比、排名。例如:
metric_A__sameperiod__yoy__growth,不需要 metricDefinitions[{"granularity": "DAY", "calculateType": "AVG"}],不要在 dimensions 中加 metric_time__day(那样是按天展开,不是日均)retail_amt + timeConstraint 上月,dimensions 为空,不要加 metric_time__day 展开⚠️ 构建查询前,必须先通过 Gateway API 检索指标和维度,禁止凭记忆猜测。
从用户问题中提取核心业务关键词,调用 Gateway 搜索(支持逗号分隔批量搜索):
# 单个关键词 curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=5" --data-urlencode "keyword=客单价" -G # 多个关键词(逗号分隔,中英文逗号均可) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=3" --data-urlencode "keyword=客单价,销售额" -G
返回纯文本格式(已过滤非 ONLINE 指标),每行一个指标:
[客单价] 3 metric(s): - AOV | 客单价 | 销售金额/购买客户数 (53 dims) - l7d_AOV | 近7天客单价 [DERIVED] (53 dims) [销售额] 2 metric(s): - retail_amt | 销售金额 | 销售金额求和 (53 dims)
AOV 是 metricName,放入 metrics 数组[DERIVED] = 派生指标,(53 dims) = 可用维度数量每次构建都做以下检查:
[DERIVED] 指标使用前必须确认其展示名语义与用户意图完全一致。对 Step 1 选定的指标,调用 Gateway 获取可用维度。支持单指标和批量指标两种方式:
# 单指标维度(路径参数直接用 metricName) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" # 单指标 + keyword 过滤(大幅减少返回量,keyword 支持逗号分隔多关键词,匹配任一即返回) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" --data-urlencode "keyword=渠道" -G # 多关键词过滤维度(同时搜索多个维度方向,匹配维度名/展示名/描述/维度值样本中任一关键词) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/AOV/dimensions" --data-urlencode "keyword=渠道,地区,品牌" -G # 批量指标维度(逗号分隔,自动计算维度交集,keyword 同样支持多关键词) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/dimensions?metricNames=AOV,retail_amt" --data-urlencode "keyword=渠道" -G
单指标返回格式:
Metric '客单价' (AOV), 53 dimension(s): - first_channel(一级渠道): Direct, E-commerce, Retail, Wholesale - gender(性别): 女, 男
批量指标返回格式(包含各指标维度 + 交集):
## 客单价 (AOV), 2 dim(s): - first_channel(一级渠道): Direct, E-commerce, Retail, Wholesale - second_channel(二级渠道): Offline, Online ## 销售金额 (retail_amt), 2 dim(s): - first_channel(一级渠道): Direct, E-commerce, Retail, Wholesale - second_channel(二级渠道): Offline, Online ## COMMON dimensions (intersection), 2 dim(s): - first_channel(一级渠道): Direct, E-commerce, Retail, Wholesale - second_channel(二级渠道): Offline, Online
first_channel 是 dimName,放入 dimensions / filters⚠️ 优先使用 keyword 过滤:当用户提到了具体的维度名或维度值(如"渠道""淘宝""女装"),用 keyword 参数过滤,只返回匹配的维度。keyword 支持逗号分隔多关键词(中英文逗号均可),匹配任一关键词即返回该维度,适合一次性搜索多个维度方向(如 keyword=渠道,地区,品牌)。匹配范围包括维度名、展示名、描述和维度值样本。
⚠️ 多指标查询必须用批量接口:一次拿到交集,避免多次调用。
每次构建都做以下检查:
__day, __month, __year 等)按指标类型限制:DERIVED 类型的时间限定派生指标通常仅支持 __day 粒度keyword=淘宝 → 返回 order_platform_code(订单来源平台): ..., 天猫淘宝, ...,直接用 order_platform_code 维度,filter 值为 天猫淘宝contains() 模糊匹配或告知用户值可能不存在请求体为标准 JSON。所有字符串值内部的双引号必须转义为 "。
"filters": ["[dim_A]= "value_1""] "timeConstraint": "DateTrunc(['metric_time'], "MONTH") = "2025-04-01""
"metrics": ["metric_A", "metric_B"]
快速计算不可链式叠加(铁律 5): 每个指标只能应用一次快速计算。需要多步计算时用 metricDefinitions 分步。
语法: {指标}__sameperiod__{偏移粒度}__{方法}
偏移粒度:
| 用户说 | 偏移粒度 | 用户说 | 偏移粒度 | |
|---|---|---|---|---|
| 日环比 | dod |
对比上月末 | moeom |
|
| 周环比 | wow |
对比上季末 | qoeoq |
|
| 月环比 | mom |
对比去年末 | yoeoy |
|
| 季环比 | qoq |
对比上月初 | mosom |
|
| 年同比 | yoy |
对比去年初 | yosoy |
所有偏移粒度支持 {N}_ 前缀(如 -2_yoy = 2年前同期)。
选择规则: "同比"→详见铁律 4;"环比"→按粒度选
dod/wow/mom/qoq。仅当用户明确说"对比XX期末/期初"时才用期末/期初偏移。
方法:
| 用户说 | 方法 | 计算 |
|---|---|---|
| 同期/环比的值 | value |
对比期原值 |
| 增长了多少 | growthvalue |
当前 − 对比 |
| 增长率/增速 | growth |
(当前 − 对比) / 对比 |
| 下降了多少 | decrease |
对比 − 当前 |
| 下降率 | decreaserate |
(对比 − 当前) / 对比 |
约束: metric_time 须在 dimensions 或 timeConstraint 中出现;偏移粒度不可小于 metric_time 粒度;期末/期初偏移仅 metric_time__day 粒度可用。
已有时间限定指标叠加同环比: 候选指标中名称含时间限定后缀(如 _ytd、_mtd 等)的派生指标,可以叠加 __sameperiod__ 快速计算,但必须:dimensions 含 metric_time__day,有 timeConstraint 锚定具体日期。推荐用 metricDefinitions + period + indirections 替代,语义更清晰。
语法: {指标}__proportion__{范围维度}
数学含义: 占比 = 当前行值 / 范围维度分组的汇总值
| 范围维度写法 | 分母 |
|---|---|
proportion__(⚠️ 末尾有两个下划线,后面无维度名) |
全部数据汇总(全局占比) |
proportion__dim_A |
按 dim_A 每组分别汇总(组内占比) |
选择规则: 问"这一行占谁的比"。"占总体"→留空;"占 A 组内"→填 A。
⚠️ 前提条件 — dimensions 必须包含参与占比计算的维度: 使用 proportion__(全局占比)时,参与占比计算的实体维度(如渠道、品牌)必须出现在 dimensions 中,否则系统无法按该维度分组计算占比。
"dimensions": [] + proportion__ → 没有分组维度,无法计算占比"dimensions": ["first_channel"] + proportion__ → 按渠道分组,计算各渠道全局占比⚠️ 陷阱一 — 恒为 100%: 范围维度覆盖了 dimensions 中所有非日期维度时,每行分母就是自己,占比恒为 100%。例如 dimensions: ["dim_A"] + proportion__dim_A → 100%。应改用 proportion__。
⚠️ 陷阱二 — filters 缩小分母: filters 在占比计算前过滤数据。如果用 filters 只留一个维度值,再算 proportion__,分母只有该值自身,占比恒为 100%。正确做法:用 resultFilters 做展示筛选。详见 §3.4 和示例 5.12。
语法: {指标}__{方式}__{顺序}__{范围维度}
rank(并列跳号)、rankDense(并列不跳)、rowNumber(不并列)desc(大=1)、asc(小=1)陷阱与占比完全相同: 范围维度覆盖所有非日期维度 → 恒为 1;filters 缩小范围 → 排名失真。用 resultFilters 做展示筛选。
语法: {指标}__period__{限定}
| 类型 | 语法示例 |
|---|---|
| 近N期 | 7d, 3w, 6m, 2q, 1y |
| 本期至今 | ytd, qtd, mtd, wtd |
| 当前期间 | cy, cq, cm, cw, cd |
约束: 被引用指标不能已有时间限定;必须有明确的时间锚定(timeConstraint 或 dimensions 中的 metric_time)。
⚠️ 核心规则(铁律 2)— 必须双重注册: metricDefinitions 中的每一个 key 都必须同时出现在 metrics 数组中(含辅助指标)。
临时指标命名: 必须与所有已有指标名称不同,避免命名冲突。建议加业务前缀/后缀以示区分。
"metrics": ["my_temp_metric"],
"metricDefinitions": {
"my_temp_metric": { "refMetric": "metric_A", ... }
}
可配置属性:
| 属性 | 说明 | 约束 |
|---|---|---|
refMetric |
引用已有指标 | |
expr |
复合表达式 "[m1]+[m2]" |
可引用其他临时指标 |
period |
时间限定 | 仅支持相对偏移;of 后锚定粒度不可细于 timeConstraint 粒度 |
metricGrain |
时间粒度 | DAY/WEEK/MONTH/QUARTER/YEAR |
preAggs |
时间维度多层聚合 | 格式为数组 [{...}];必须配合 period |
filters |
业务限定 | 支持维度筛选和 MetricMatches |
indirections |
衍生方式 | 同环比/占比/排名/多层聚合 |
specifyDimension |
聚合维度控制 | EXCLUDE 排除外层分组影响 |
仅支持相对日期偏移,基于 timeConstraint 锚定的日期做偏移。
of 后锚定粒度规则: of 后的粒度不可细于 timeConstraint 锚定粒度。
of 可用 day、week、month、quarter、yearof 可用 month、quarter、year(不可用 day、week)to_date(区间:偏移日 ~ 锚定日):
"to_date -6 day of 0 day" → 基准日前6天 ~ 基准日(共7日) "to_date -29 day of 0 day" → 共30日 "to_date -7 day of -1 day" → 基准日前8天 ~ 前1天(共7日,不含基准日)
grain_to_date(某粒度起点 ~ 锚定点):
"grain_to_date 0 year of 0 day" → 本年初 ~ 基准日(本年至今) "grain_to_date 0 month of 0 day" → 本月初 ~ 基准日(本月至今) "grain_to_date -1 year of -1 day" → 去年初 ~ 去年的基准日前1天 "grain_to_date 0 year of 0 month" → 本年初 ~ 基准月(锚定到月时)
relative_date(单一日期/月定位):
"relative_date 0 month of 0 day" → 基准日所在月 "relative_date -1 month of 0 day" → 上月 "relative_date -5 month of 0 month" → 5个月前(锚定到月时)
SPECIFY_DATE(期初/期末定位):
"SPECIFY_DATE start day of -1 year" → 上年第一天 "SPECIFY_DATE end day of -1 month" → 上月最后一天 "SPECIFY_DATE end day of -1 year" → 上年最后一天 "SPECIFY_DATE end month of -1 year" → 上年最后一个月
period 与 timeConstraint 配合:
of 0 day 表示该天of 0 month 表示该月relative_date -5 month of 0 month 定位1月格式为数组,必须配合 period。
"preAggs": [{"granularity": "DAY", "calculateType": "AVG"}]
granularity: DAY / WEEK / MONTH / QUARTER / YEARcalculateType: AVG / MAX / MIN典型场景: "近30天日均" = period 限定30天 + preAggs 按 DAY 求 AVG。
⚠️ preAggs 与 dimensions 中的时间粒度: 使用 preAggs 按 DAY 聚合时,不要在外层 dimensions 中放 metric_time__day。preAggs 已经按日聚合再取 AVG/MAX/MIN,如果外层再按天展开,等于没有聚合。同理,preAggs 按 MONTH 聚合时不要在 dimensions 中放 metric_time__month。
preAggs + 同比: 含 preAggs 时不能直接叠加 __sameperiod__。须分别定义今年和去年的临时指标(各自含 period + preAggs),再用 expr 计算增长率。见示例 5.13。
临时指标可附加维度筛选:
"my_metric": {
"refMetric": "metric_A",
"filters": ["[dim_X]= "value_1""]
}
MetricMatches — 基于指标值筛选维度值,再用筛选后的维度值计算指标:
MetricMatches([维度名], [指标名] 运算符 值)
MetricMatches vs resultFilters: 同指标筛选("指标A≥某值的维度有哪些")→ resultFilters;跨指标筛选("指标A≥某值的维度有多少个"→ 用 A 筛维度值,再算 B)→ MetricMatches。
MetricMatches 约束: 每个 MetricMatches 仅支持一个指标条件。多指标条件须拆分为多个 MetricMatches(数组内为 AND):
"filters": [
"MetricMatches([dim_X], [metric_C] > 30)",
"MetricMatches([dim_X], [metric_D] < 0.2)"
]
"indirections": ["sameperiod__yoy__value"] → 年同比 "indirections": ["proportion__dim_A"] → dim_A 组内占比 "indirections": ["rank__desc__dim_A"] → dim_A 组内排名 "indirections": ["multi_level_agg__avg,dim_A"] → 非时间维度多层聚合
多层聚合选择: 时间维度多层聚合 → preAggs + period;非时间维度多层聚合 → indirections 的 multi_level_agg。
period + indirections 组合(推荐): 不含 preAggs 的 period 指标做同环比 → 用 period + indirections: ["sameperiod__yoy__growth"]。含 preAggs 时不可用此组合,须手动分两步 + expr。
multi_level_agg 与外层 dimensions 冲突: 当聚合维度同时在外层 dimensions 中时,结果恒等于自身。必须添加 specifyDimension: { "type": "EXCLUDE", "dimensions": "dim_X" }。
日期维度支持粒度后缀:__year, __quarter, __month, __week, __day。
⚠️ 粒度后缀必须全部小写: 维度名中的粒度后缀(__day, __month, __year, __week, __quarter)必须使用小写字母。这是 API 的硬性要求,大写会导致查询失败或返回空结果。
metric_time__day, metric_time__month, metric_time__yearmetric_time__DAY, metric_time__MONTH, metric_time__YEAR(大写后缀 = 错误)同理,orders 中引用维度名时也必须保持小写:
{"metric_time__day": "asc"}{"metric_time__DAY": "asc"}"dimensions": ["metric_time__month", "dim_A"]
⚠️ 维度兼容性校验: 多指标查询时,dimensions 只能包含所有指标都支持的维度(取交集)。详见 §1 候选指标表检查 3。
| filters | resultFilters | |
|---|---|---|
| 等价于 | SQL WHERE | SQL HAVING |
| 影响 | 计算过程(分母、排名范围都会被影响) | 仅过滤返回行 |
选择规则:
timeConstraint(⚠️ 禁止放 filters)resultFiltersfiltersresultFiltersfilters 语法:
[dim_A]= "value" 精确匹配 IN([dim_A], "v1", "v2") 包含 NotIn([dim_A], "v1") 排除 contains([dim_A], "x") 模糊 [dim_num]>= 100 数值比较 ['date_dim']>= "2023-08-01" 日期比较
resultFilters 语法:
"resultFilters": ["[metric_M] > 1000"] "resultFilters": ["[metric_M__sameperiod__mom__growth] > 0.05"] "resultFilters": ["[dim_A]= "value_1""]
timeConstraint 有两个不同的角色,构建时必须区分:
| 角色 | 说明 | 形式 |
|---|---|---|
| 角色 A:时间范围过滤 | 限定"查哪段时间的数据" | 一个区间(如近7天、上月) |
| 角色 B:period 锚定基准 | 给 period/sameperiod 提供相对偏移的基准点 | 一个具体日期或月份 |
📋 timeConstraint 速查表(根据用户时间表达直接查表复制):
| 用户说 | timeConstraint |
|---|---|
| 昨天 | "['metric_time__day']= DATEADD(DateTrunc(NOW(), "DAY"), -1, "DAY")" |
| 今天 | "['metric_time__day']= DateTrunc(NOW(), "DAY")" |
| 上周 | "DateTrunc(['metric_time'], "WEEK") = DATEADD(DateTrunc(NOW(), "WEEK"), -1, "WEEK")" |
| 本周 | "DateTrunc(['metric_time'], "WEEK") = DateTrunc(NOW(), "WEEK")" |
| 上月 | "DateTrunc(['metric_time'], "MONTH") = DATEADD(DateTrunc(NOW(), "MONTH"), -1, "MONTH")" |
| 本月 | "DateTrunc(['metric_time'], "MONTH") = DateTrunc(NOW(), "MONTH")" |
| 上季 | "DateTrunc(['metric_time'], "QUARTER") = DATEADD(DateTrunc(NOW(), "QUARTER"), -1, "QUARTER")" |
| 本季 | "DateTrunc(['metric_time'], "QUARTER") = DateTrunc(NOW(), "QUARTER")" |
| 本年 | "DateTrunc(['metric_time'], "YEAR") = DateTrunc(NOW(), "YEAR")" |
| 去年 | "DateTrunc(['metric_time'], "YEAR") = DATEADD(DateTrunc(NOW(), "YEAR"), -1, "YEAR")" |
| 近7天 | "DateTrunc(['metric_time'], "DAY") >= DATEADD(DateTrunc(NOW(), "DAY"), -7, "DAY") AND ['metric_time__day'] < DateTrunc(NOW(), "DAY")" |
| 近30天 | "DateTrunc(['metric_time'], "DAY") >= DATEADD(DateTrunc(NOW(), "DAY"), -30, "DAY") AND ['metric_time__day'] < DateTrunc(NOW(), "DAY")" |
| 近12个月 | "DateTrunc(['metric_time'], "MONTH") >= DATEADD(DateTrunc(NOW(), "MONTH"), -12, "MONTH") AND DateTrunc(['metric_time'], "MONTH") < DateTrunc(NOW(), "MONTH")" |
| 2025年4月(具体月份) | "DateTrunc(['metric_time'], "MONTH") = "2025-04-01"" |
| 2025-06-15(具体日期) | "['metric_time__day']= "2025-06-15"" |
⚠️ 表中除最后两行外,全部使用 NOW()(详见铁律 1)。只有用户指定了具体日期/月份才用字面日期。
用户未指定时间时的默认策略(⚠️ 从上到下匹配,命中第一行即停止):
| 优先级 | 条件 | 默认 timeConstraint | 说明 |
|---|---|---|---|
| 1 | 查询中有 period / __period__ / 已有时间限定派生指标 |
锚定昨天(角色 B) | period 自身定义时间窗口,timeConstraint 只提供基准点 |
| 2 | 查询中有 __sameperiod__mom__
|