metrics
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMetrics
指标
A metric is a measure of the semantic model, fully qualified:
. The app's Metrics page lists every measure of the
cubes built from data sources, and a metric's own page lets you count it over
a scope (a segment, or a few conditions) and break it down by a
dimension — the same three settings a dashboard card stores. This skill reads
only; nothing here writes.
crm_deals.amountFor ad-hoc analytical questions that aren't about one metric — several
measures at once, custom grouping, top-N across cubes — the
semantic-model skill is the better fit. Use this one when the user
thinks in terms of a named metric, or wants the number a card shows.
**指标(metric)**是 semantic model 的一种度量,其完整限定名为:。应用的 Metrics 页面会列出由 data sources 构建的 cubes 中的每项 measure,而指标自己的页面可让你在一个 scope(一个 segment,或若干 conditions)内统计该指标,并按 dimension 拆分——这与 dashboard card 保存的三项设置完全相同。本 skill 仅执行读取操作;这里不会写入任何内容。
crm_deals.amount对于并非针对单个指标的临时分析问题——同时分析多个 measures、自定义分组、跨 cubes 做 top-N——semantic-model skill 更合适。当用户以命名指标的方式思考,或想获取 card 所显示的数值时,使用本 skill。
The catalogue
指标目录
json
api_read { "resource": "cubes", "method": "meta", "params": { "fields": "name,title,description,type", "pageSize": 100 } }
api_read { "resource": "cubes", "method": "meta", "params": { "filter": "name == \"crm_deals\"" } }The app lists measures of source cubes only. Leave out:
- — a table's view (
type: "view") re-exports measures under new names; each such measure'smodel_…points at the original;aliasMember - generated cubes, marked — segment snapshots (
meta.abConnectionId: "revos") and tables' own columns (segment_…).model_stream_…can't be projected withmeta; it's on the full record you read for a candidate cube anyway.fields
Per measure, what the catalogue shows:
| Column | From |
|---|---|
| Metric | |
| Cube | the cube's |
| Agg | |
| Format | |
Only measures can be counted on a card; say so if the user
picks a text, boolean, or time one.
type: "number"When the user asks for a metric by meaning ("win rate", "ARR"), search titles
and descriptions. If nothing matches, say so and offer the closest, or adding
one with the cubes skill — never approximate silently with a different
measure.
json
api_read { "resource": "cubes", "method": "meta", "params": { "fields": "name,title,description,type", "pageSize": 100 } }
api_read { "resource": "cubes", "method": "meta", "params": { "filter": "name == \"crm_deals\"" } }应用只列出 source cubes 的 measures。需要排除:
- ——某个 table 的 view(
type: "view")会以新名称重新导出 measures;每个此类 measure 的model_…都指向原始 measure;aliasMember - 生成的 cubes,标记为 ——即 segment 快照(
meta.abConnectionId: "revos")和 tables 自身的 columns(segment_…)。model_stream_…不能通过meta进行投影;不过,读取候选 cube 的完整记录时,其中本来就会包含fields。meta
目录针对每个 measure 展示以下信息:
| 列 | 来自 |
|---|---|
| 指标 | |
| Cube | cube 的 |
| 聚合 | |
| 格式 | |
只有 的 measure 可以在 card 上统计;如果用户选择的是 text、boolean 或 time measure,要明确指出这一点。
type: "number"当用户按含义询问指标(“win rate”“ARR”)时,搜索 titles 和 descriptions。如果没有匹配项,明确说明,并提供最接近的选项,或建议使用 cubes skill 添加一个——绝不能悄悄用另一项 measure 近似替代。
Where a metric is used
指标的使用位置
- Tables: a view re-exports the measure (
model_<table id, '-' → '_'>). Map the id back withaliasMember == "<measure>".api_read { "resource": "tables", "params": { "fields": "id,name" } } - Segments: the measure (or a view alias of it) is a in the segment's
member.filter - Dashboards: .
api_read { "resource": "dashboard-cards", "params": { "filter": "measure == \"<measure>\"" } }
- Tables:一个 view 会重新导出该 measure(
model_<table id, '-' → '_'>)。可通过aliasMember == "<measure>"将 id 映射回去。api_read { "resource": "tables", "params": { "fields": "id,name" } } - Segments:该 measure(或它的 view alias)是 segment 中的
filter。member - Dashboards:。
api_read { "resource": "dashboard-cards", "params": { "filter": "measure == \"<measure>\"" } }
A metric's value
指标值
api_read { "resource": "cubes", "method": "query", "body": { "query": … } }json
{
"measures": ["<measure>"],
"filters": [ <the scope's conditions, as Cube filters> ],
"joinHints": [ <each join path, split on "."> ]
}Leave out / when empty.
filtersjoinHintsapi_read { "resource": "cubes", "method": "query", "body": { "query": … } }json
{
"measures": ["<measure>"],
"filters": [ <the scope's conditions, as Cube filters> ],
"joinHints": [ <each join path, split on "."> ]
}当 / 为空时将其省略。
filtersjoinHintsScope
统计范围(Scope)
- Every row — no filters.
- Conditions — written in segment filter syntax (see the segments
skill's ) and translated with its table:
references/filter-syntax.md→EQUAL,equals→EMPTY,notSet→CHECKED, … Top-levelequals "true"items are separateANDentries; anfiltersbecomesOR, an{ "or": [ … ] }groupAND. Skip conditions with no{ "and": [ … ] }, or nomemberwhere the operator needs one — the app does too. Check stored values with a cubes query before anvalueon a string.EQUAL - A dynamic segment — read it; translate its the same way, and put its
filterintocubes[1..].joinPathfirst.joinHints - A static segment — one filter instead of its conditions:
. It needs that
{ "member": "segment_<segment id, '-' → '_'>.id", "operator": "set" }cube insegment_….meta
A segment fits a metric only when its root cube is the metric's cube
(). A segment of companies can't scope a deal
metric — say so, and offer conditions on the company fields instead.
segment.cubes[0].joinPath-
所有行——不带 filters。
-
Conditions——使用 segment filter syntax 编写(见 segments skill 的),并按照其对照表转换:
references/filter-syntax.md→EQUAL,equals→EMPTY,notSet→CHECKED,…… 顶层equals "true"项要分别作为独立的AND条目;filters转换为OR,{ "or": [ … ] }group 转换为AND。跳过没有{ "and": [ … ] }的 conditions,或在 operator 需要 value 时没有member的 conditions——应用也会跳过。先通过 cubes query 检查存储值,再对字符串使用value。EQUAL -
动态 segment——读取它;同样转换它的,并首先将其
filter放入cubes[1..].joinPath。joinHints -
静态 segment——用一个 filter 代替其 conditions:
{ "member": "segment_<segment id, '-' → '_'>.id", "operator": "set" }它需要中存在该metacube。segment_…
只有当 segment 的 root cube 与指标的 cube 相同时(),该 segment 才能用于该指标。companies 的 segment 不能限定 deal 指标——应明确说明,并改为提供 company fields 上的 conditions。
segment.cubes[0].joinPathJoins to other cubes
与其他 cubes 的 joins
A condition or breakdown on another cube reads it along a join path from
the metric's cube: . Check each hop against
in (declared on either side). When two routes exist, the choice
changes the number — ask which the user means. Send each path as a join
hint, ; the metric's own cube needs none.
crm_deals.crm_companiesjoinsmeta["crm_deals", "crm_companies"]Two conditions the app refuses, and you should too:
- A condition on a measure (). On a total it isn't per-row; it's not a scope.
crm_deals.count > 3 - A condition on a cube the metric's rows have many of (/
hasManyalong the path): each row is checked once per related row.one_to_many
对另一个 cube 的 condition 或 breakdown,需要沿指标 cube 出发的 join path 读取它:。根据 中的 逐跳检查(可在任一侧声明)。存在两条路径时,不同选择会改变数值——询问用户指的是哪一条。每条路径都作为 join hint 发送,;指标自身的 cube 不需要。
crm_deals.crm_companiesmetajoins["crm_deals", "crm_companies"]应用会拒绝以下两种 conditions,你也应拒绝:
- 对 measure 的 condition()。对于 total,它并非按行生效,因此不能作为 scope。
crm_deals.count > 3 - 对指标行具有多个关联项的 cube 的 condition(路径上为 /
hasMany):每一行会针对每个相关行检查一次。one_to_many
Breakdown
拆分(Breakdown)
The same query plus the dimension:
- not a time dimension: ,
"dimensions": ["<dim>"]— largest groups first."order": { "<measure>": "desc", "<dim>": "asc" } - a time dimension: ,
"timeDimensions": [{ "dimension": "<dim>", "granularity": "month" }]— latest months first."order": { "<dim>": "desc" }
The groups add up to the total only for a or measure whose
breakdown doesn't go along a join the rows have many of. Otherwise don't
present shares or an "Other" bucket, and for a fanned-out breakdown, say a
record linked to several groups is counted in each. A card shows the top 5
plus "Other"; the metric page shows 50.
countsum在同一个 query 中加入 dimension:
- 非 time dimension:,
"dimensions": ["<dim>"]——最大的 groups 排在前面。"order": { "<measure>": "desc", "<dim>": "asc" } - time dimension:,
"timeDimensions": [{ "dimension": "<dim>", "granularity": "month" }]——最近的 months 排在前面。"order": { "<dim>": "desc" }
只有当 measure 为 或 ,且其 breakdown 没有沿着指标行存在多关联项的 join 时,各 groups 的总和才等于 total。否则,不要展示占比或“Other” bucket;对于发生 fan-out 的 breakdown,要说明一条关联到多个 groups 的 record 会在每个 group 中分别计数。card 展示 top 5 加“Other”;指标页面展示 50 条。
countsumReading the answer
解读结果
- No rows: a count, count distinct, or sum is ; an average or other measure has no value — say "no value", not
0.0 - Format with the measure's (currency, percent).
format - Always say what the number is counted over: "€1.2M open pipeline, deals in the EMEA segment".
- on the result says how fresh it is; mention it when it's old or
metadata.lastRefreshTimeis set.slowQuery
Render a single value as one line, a breakdown as a small table, or a chart
when it helps.
- 没有行:对于 count、count distinct 或 sum,值为 ;对于 average 或其他 measure,则没有值——应说“无值”,而不是
0。0 - 使用 measure 的 进行格式化(currency、percent)。
format - 始终说明数字的统计范围:“€1.2M open pipeline,deals 位于 EMEA segment 中”。
- 表明结果的新鲜度;当它过旧或设置了
metadata.lastRefreshTime时,应提及。slowQuery
将单一值呈现为一行,将 breakdown 呈现为小型 table,或在有助于表达时使用 chart。