跳转至

指标树归因

1. 功能概述

指标树归因用于分析一个复杂指标的变化来源。系统先把指标拆解成指标树,再按树上的计算关系逐层计算每个节点在当前对象和对比对象之间的变化。

适用场景:

  • 分析复合指标的增长或下降来自哪些子指标。
  • 对同一个指标做当前时间与历史时间对比。
  • 对同一个指标做当前对象与对比对象的同类对比,例如不同门店、品牌、区域之间的对比。

指标树归因支持两类接口:

  • 时间对比归因:tree_time_compare
  • 同类对比归因:tree_peer_compare

两个接口的请求主体都包含 metricTreeDefattribution。区别在于 attribution 中描述对比对象的方式不同。

建议调用流程:

  1. 调用指标归因校验接口,确认指标支持归因。
  2. 调用指标拆解接口 breakdown,获取 metricTreeDef
  3. 使用 metricTreeDef 调用指标树归因接口。
  4. 从响应 data 中读取各节点的当前值、对比值、增长值、增长率和相对贡献率。

2. 接口 URL

时间对比归因

POST /anymetrics/api/v1/attribution/tree_time_compare

用于比较同一指标树在两个时间范围内的变化。

同类对比归因

POST /anymetrics/api/v1/attribution/tree_peer_compare

用于比较同一指标树在两个对象之间的差异。对象可以通过维度过滤条件表达,例如品牌、门店、城市等。

3. 公共请求参数(HEADERS)

参数名 类型 必选 描述
tenant-id String 租户空间标识
auth-type String 认证方式。支持 UIDTOKENACCOUNTAPIKEY
auth-value String auth-type 对应的认证值

公共参数获取方式:

tenant-id 可在 Aloudata CAN 顶部导航栏选择指标应用,左边菜单栏选择 API 集成,在 API 集成界面获取;auth-value 请按 auth-type 填写对应认证值。

image.png


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 归因计算方式兼容字段。可传 ALLAVG
currentTimeConstraint String 当前时间范围表达式
compareTimeConstraint String 对比时间范围表达式

时间对比会把 filters + currentTimeConstraint 作为当前值查询条件,把 filters + compareTimeConstraint 作为对比值查询条件。

同类对比:tree_peer_compare

字段名 类型 必选 描述
filters List 全局过滤条件,会同时作用于当前对象和对比对象
attributionCalculateType String 归因计算方式兼容字段。可传 ALLAVG
timeConstraint String 公共时间范围表达式,会同时作用于当前对象和对比对象
compareDimension String 对比维度名称,当前接口主要通过 currentObjectcompareObject 的过滤条件确定对象
currentObject Object 当前对象,包含对象过滤条件和时间条件
compareObject Object 对比对象,包含对象过滤条件和时间条件

currentObjectcompareObject 结构:

字段名 类型 必选 描述
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.timeConstraintcompareObject.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、表达式结果不可计算或数据为空时,部分数值字段可能为 nullNaN 或不返回,调用方需要做展示兜底。

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、请求参数和错误信息,并提供给服务端排查。