指标树归因
1. 功能概述
指标树归因用于分析一个复杂指标的变化来源。系统先把指标拆解成指标树,再按树上的计算关系逐层计算每个节点在当前对象和对比对象之间的变化。
适用场景:
- 分析复合指标的增长或下降来自哪些子指标。
- 对同一个指标做当前时间与历史时间对比。
- 对同一个指标做当前对象与对比对象的同类对比,例如不同门店、品牌、区域之间的对比。
指标树归因支持两类接口:
- 时间对比归因:
tree_time_compare - 同类对比归因:
tree_peer_compare
两个接口的请求主体都包含 metricTreeDef 和 attribution。区别在于 attribution 中描述对比对象的方式不同。
建议调用流程:
- 调用指标归因校验接口,确认指标支持归因。
- 调用指标拆解接口
breakdown,获取metricTreeDef。 - 使用
metricTreeDef调用指标树归因接口。 - 从响应
data中读取各节点的当前值、对比值、增长值、增长率和相对贡献率。
2. 接口 URL
时间对比归因
用于比较同一指标树在两个时间范围内的变化。
同类对比归因
用于比较同一指标树在两个对象之间的差异。对象可以通过维度过滤条件表达,例如品牌、门店、城市等。
3. 公共请求参数(HEADERS)
| 参数名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| tenant-id | String | 是 | 租户空间标识 |
| auth-type | String | 是 | 认证方式。支持 UID、TOKEN、ACCOUNT、APIKEY |
| auth-value | String | 是 | 与 auth-type 对应的认证值 |
公共参数获取方式:
tenant-id 可在 Aloudata CAN 顶部导航栏选择指标应用,左边菜单栏选择 API 集成,在 API 集成界面获取;auth-value 请按 auth-type 填写对应认证值。

4. 请求参数(Request Body)
| 字段名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| metricTreeDef | Object | 是 | 指标树定义。通常直接使用指标拆解接口 breakdown 的返回结果 |
| attribution | Object | 是 | 归因计算配置。时间对比和同类对比的结构不同 |
4.1 metricTreeDef 结构说明
metricTreeDef 表示一棵指标树,通常由指标拆解接口返回。
| 字段名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| rootNode | String | 是 | 根节点 ID,即本次归因要分析的主指标节点 |
| metricTree | Map |
是 | 指标树计算关系。key 为父节点 ID,value 为父节点的拆解表达式 |
| metricTreeNodes | Map |
是 | 节点 ID 与指标 code 或临时指标 ID 的映射 |
| metricDefinitions | Map |
否 | 临时指标定义。节点引用临时指标时需要传入 |
metricTree 中的表达式通过 [节点ID] 引用子节点。例如:
{
"rootNode": "node_001",
"metricTree": {
"node_001": "[node_002] - [node_003]",
"node_002": "[node_004] * [node_005]"
},
"metricTreeNodes": {
"node_001": "profit",
"node_002": "revenue",
"node_003": "cost",
"node_004": "order_count",
"node_005": "price"
},
"metricDefinitions": {}
}
说明:
metricTree只需要描述可继续拆分的父节点。叶子节点没有子节点,可不出现在metricTree中。metricTreeNodes需要包含树上所有节点,包括根节点、中间节点和叶子节点。- 如果
metricTreeNodes中某个节点指向临时指标,需在metricDefinitions中提供该临时指标定义。
4.2 attribution 结构
时间对比:tree_time_compare
| 字段名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| filters | List |
否 | 全局过滤条件,会同时作用于当前时间和对比时间 |
| attributionCalculateType | String | 否 | 归因计算方式兼容字段。可传 ALL 或 AVG |
| currentTimeConstraint | String | 是 | 当前时间范围表达式 |
| compareTimeConstraint | String | 是 | 对比时间范围表达式 |
时间对比会把 filters + currentTimeConstraint 作为当前值查询条件,把 filters + compareTimeConstraint 作为对比值查询条件。
同类对比:tree_peer_compare
| 字段名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| filters | List |
否 | 全局过滤条件,会同时作用于当前对象和对比对象 |
| attributionCalculateType | String | 否 | 归因计算方式兼容字段。可传 ALL 或 AVG |
| timeConstraint | String | 否 | 公共时间范围表达式,会同时作用于当前对象和对比对象 |
| compareDimension | String | 否 | 对比维度名称,当前接口主要通过 currentObject 和 compareObject 的过滤条件确定对象 |
| currentObject | Object | 是 | 当前对象,包含对象过滤条件和时间条件 |
| compareObject | Object | 是 | 对比对象,包含对象过滤条件和时间条件 |
currentObject 和 compareObject 结构:
| 字段名 | 类型 | 必选 | 描述 |
|---|---|---|---|
| filters | List |
否 | 对象过滤条件,例如 [brand]="百味" |
| timeConstraint | String | 否 | 对象时间范围表达式。未传时仅使用公共 timeConstraint |
同类对比会把 filters + timeConstraint + currentObject.filters + currentObject.timeConstraint 作为当前对象查询条件,把 filters + timeConstraint + compareObject.filters + compareObject.timeConstraint 作为对比对象查询条件。
5. 请求示例
5.1 时间对比示例(tree_time_compare)
{
"metricTreeDef": {
"rootNode": "node_693597278",
"metricTree": {
"node_693597278": "(([node_2083930844])) / ([node_1553155881])"
},
"metricTreeNodes": {
"node_2083930844": "sum_quantity1",
"node_1553155881": "countDistinct_sales_id",
"node_693597278": "avgslM06"
},
"metricDefinitions": {}
},
"attribution": {
"filters": [],
"attributionCalculateType": "ALL",
"currentTimeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-07\"",
"compareTimeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-06\""
}
}
5.2 同类对比示例(tree_peer_compare)
{
"metricTreeDef": {
"rootNode": "node_693597278",
"metricTree": {
"node_693597278": "(([node_2083930844])) / ([node_1553155881])"
},
"metricTreeNodes": {
"node_2083930844": "sum_quantity1",
"node_1553155881": "countDistinct_sales_id",
"node_693597278": "avgslM06"
},
"metricDefinitions": {}
},
"attribution": {
"filters": [],
"attributionCalculateType": "AVG",
"timeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-07\"",
"currentObject": {
"filters": [
"[brand]=\"百味\""
]
},
"compareObject": {
"filters": [
"[brand]=\"典范\""
]
}
}
}
也可以把时间条件分别放在 currentObject.timeConstraint 和 compareObject.timeConstraint 中,用于比较不同对象在不同时间范围内的差异。
6. 响应结构说明
接口成功时返回统一响应结构,业务结果位于 data 字段中。
| 字段名 | 类型 | 描述 |
|---|---|---|
| data | Object | 指标树归因结果。key 为节点 ID,value 为该节点的归因结果 |
| success | Boolean | 请求是否成功 |
| code | String | 响应码,例如 "200" |
| errorMsg | String | null | 错误信息。成功时通常为 null |
| detailErrorMsg | String | null | 详细错误信息 |
| traceId | String | 链路追踪 ID。排查问题时请提供该值 |
data 示例结构:
{
"node_001": {
"@currentValue": 10.0,
"@compareValue": 12.0,
"@growth": -2.0,
"@growthRate": -0.166667
},
"node_002": {
"@currentValue": 20.0,
"@compareValue": 16.0,
"@growth": 4.0,
"@growthRate": 0.25,
"@relativeContributionRate": 0.6
}
}
说明:
- 根节点通常返回当前值、对比值、增长值和增长率。
- 子节点或中间节点在可计算时会返回
@relativeContributionRate。 - 当对比值为 0、表达式结果不可计算或数据为空时,部分数值字段可能为
null、NaN或不返回,调用方需要做展示兜底。
7. 字段含义解释
| 字段名 | 含义 |
|---|---|
| @currentValue | 当前时间或当前对象下的节点指标值 |
| @compareValue | 对比时间或对比对象下的节点指标值 |
| @growth | 增长值,通常为 @currentValue - @compareValue |
| @growthRate | 增长率,通常为 (@currentValue - @compareValue) / @compareValue |
| @relativeContributionRate | 相对贡献率,表示该子节点在其父节点变化中的影响占比。常用于判断同一父节点下哪些子节点贡献更大 |
贡献率理解示例:
@growth > 0表示该节点当前值高于对比值。@growth < 0表示该节点当前值低于对比值。@relativeContributionRate越大,表示该节点对父节点变化的解释力度越高。- 根节点是整棵指标树的分析目标,一般不需要再看相对贡献率。
8. 调用示例
8.1 指标树归因(时间对比)
查询请求:
curl --location --request POST 'http://127.0.0.1:8083/anymetrics/api/v1/attribution/tree_time_compare' \
--header 'auth-type: UID' \
--header 'tenant-id: tn_19487697' \
--header 'auth-value: 463663891121963008' \
--header 'Accept-Language: zh-CN' \
--header 'Content-Type: application/json' \
--data-raw '{
"metricTreeDef": {
"rootNode": "node_693597278",
"metricTree": {
"node_693597278": "(([node_2083930844])) / ([node_1553155881])"
},
"metricTreeNodes": {
"node_2083930844": "sum_quantity1",
"node_1553155881": "countDistinct_sales_id",
"node_693597278": "avgslM06"
},
"metricDefinitions": {}
},
"attribution": {
"filters": [],
"attributionCalculateType": "ALL",
"currentTimeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-07\"",
"compareTimeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-06\""
}
}'
响应示例:
{
"data": {
"node_2083930844": {
"@currentValue": 3171.0,
"@relativeContributionRate": 0.0,
"@compareValue": 3412.0,
"@growthRate": -0.070633,
"@growth": -241.0
},
"node_1553155881": {
"@currentValue": 3171.0,
"@relativeContributionRate": 0.0,
"@compareValue": 3412.0,
"@growthRate": -0.070633,
"@growth": -241.0
},
"node_693597278": {
"@currentValue": 1.0,
"@compareValue": 1.0,
"@growthRate": 0.0,
"@growth": 0.0
}
},
"success": true,
"code": "200",
"errorMsg": null,
"detailErrorMsg": null,
"traceId": "cced9e32f6aa4b3eb03905b51054ad4d.194.17780536606010059"
}
8.2 指标树归因(同类对比)
查询请求:
curl --location --request POST 'http://127.0.0.1:8083/anymetrics/api/v1/attribution/tree_peer_compare' \
--header 'auth-type: UID' \
--header 'tenant-id: tn_19487697' \
--header 'auth-value: 463663891121963008' \
--header 'Accept-Language: zh-CN' \
--header 'Content-Type: application/json' \
--data-raw '{
"metricTreeDef": {
"rootNode": "node_693597278",
"metricTree": {
"node_693597278": "(([node_2083930844])) / ([node_1553155881])"
},
"metricTreeNodes": {
"node_2083930844": "sum_quantity1",
"node_1553155881": "countDistinct_sales_id",
"node_693597278": "avgslM06"
},
"metricDefinitions": {}
},
"attribution": {
"filters": [],
"attributionCalculateType": "AVG",
"timeConstraint": "DateTrunc([metric_time],\"DAY\")=\"2025-07-07\"",
"currentObject": {
"filters": [
"[brand]=\"百味\""
]
},
"compareObject": {
"filters": [
"[brand]=\"典范\""
]
}
}
}'
响应示例:
{
"data": {
"node_2083930844": {
"@currentValue": 105397.0,
"@relativeContributionRate": 0.0,
"@compareValue": 105397.0,
"@growthRate": 0.0,
"@growth": 0.0
},
"node_1553155881": {
"@currentValue": 105397.0,
"@relativeContributionRate": 0.0,
"@compareValue": 105397.0,
"@growthRate": 0.0,
"@growth": 0.0
},
"node_693597278": {
"@currentValue": 1.0,
"@compareValue": 1.0,
"@growthRate": 0.0,
"@growth": 0.0
}
},
"success": true,
"code": "200",
"errorMsg": null,
"detailErrorMsg": null,
"traceId": "2537fe72c3f84f51892047a537d3592a.183.17780539097420057"
}
9. 使用注意事项
- 建议先调用
POST /anymetrics/api/v1/attribution/metric_check校验指标是否支持归因。 metricTreeDef建议直接使用POST /anymetrics/api/v1/attribution/breakdown的返回结果,避免手工拼接节点关系出错。- 时间表达式中的指标日期字段通常写为
[metric_time]。 - 过滤条件表达式中,字段名使用方括号包裹,例如
[brand]="百味"。 - 同类对比接口应调用
tree_peer_compare,不要使用tree_time_compare。 - 如果响应
success=false,请记录traceId、请求参数和错误信息,并提供给服务端排查。