TM 定义参考
本文面向需要编写或审查 Foggy Table Model(TM)的开发者,按定义对象和属性组织当前公开语义建模契约。本文只描述 TM 定义本身;QM 暴露字段和 DSL 查询语法请分别参考 QM 定义参考 和 JSON Query DSL 语法参考。
TM 描述物理数据如何进入 Foggy 语义层,包括物理表、字段、维度关系、指标、类型和公式。TM 字段不等于 DSL 可查询字段;字段需要进入当前 QM 的可见字段集合后,才可被查询调用方引用。预聚合属于查询引擎优化能力,本文只保留入口说明,详细能力见 预聚合能力参考。
1. TM 文件结构
TM 文件使用 JavaScript 模块语法,导出 model 对象。
export const model = {
name: 'FactSalesModel',
caption: '销售事实表',
description: '销售订单明细数据',
tableName: 'fact_sales',
idColumn: 'sales_key',
dimensions: [],
properties: [],
measures: []
};1.1 model 顶层属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | TM 唯一标识,QM 通过该名称引用 |
caption | string | 否 | 模型显示名称,可作为 AI 元数据 |
description | string | 否 | 模型语义描述,可作为 AI 上下文 |
tableName | string | 是¹ | 物理表名、视图名或集合名 |
viewSql | string | 否¹ | 视图 SQL,与 tableName 二选一 |
schema | string | 否 | 数据库 schema |
idColumn | string | 否 | 主键列名 |
type | string | 否 | 模型类型,常见值为 jdbc、mongo、vector |
dataSource | object | 否 | 宿主注入的数据源对象;公开模型通常优先使用 dataSourceName |
dataSourceName | string | 否 | 命名数据源引用 |
mongoTemplate | string | 否 | MongoDB 模板或连接配置引用,type: 'mongo' 时使用 |
vectorConfig | object | 否 | 向量模型配置,type: 'vector' 时使用 |
dimensions | array | 否 | 维度关系定义 |
properties | array | 否 | 非聚合字段定义 |
measures | array | 否 | 可聚合指标定义 |
preAggregations | array | 否 | 预聚合定义,详见 预聚合能力参考 |
autoLoadDimensions | boolean | 否 | 是否自动加载维度 |
autoLoadMeasures | boolean | 否 | 是否自动加载度量 |
ai | object | 否 | 模型级 AI 元数据配置 |
deprecated | boolean | 否 | 是否标记为废弃 |
extData | object | 否 | 自定义扩展元数据 |
¹ tableName 和 viewSql 通常二选一。
2. 维度定义
维度定义事实表与维度表之间的语义关系。引擎根据维度定义生成关联查询,LLM 不需要直接推断 JOIN 路径。
dimensions: [
{
name: 'customer',
caption: '客户',
tableName: 'dim_customer',
foreignKey: 'customer_key',
primaryKey: 'customer_key',
captionColumn: 'customer_name',
properties: [
{ column: 'customer_type', caption: '客户类型', type: 'STRING' },
{ column: 'province', caption: '省份', type: 'STRING' }
]
}
]2.1 dimension 属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 维度名,DSL 中通过 维度名$属性 引用 |
caption | string | 否 | 显示名称 |
description | string | 否 | 语义描述 |
tableName | string | 是¹ | 维度表名 |
viewSql | string | 否¹ | 维度视图 SQL |
schema | string | 否 | 维度表 schema |
dataSource | object | 否 | 宿主注入的数据源对象;默认继承 TM 数据源 |
foreignKey | string | 是 | 当前表或父维度表上的外键列 |
primaryKey | string | 是 | 维度表主键列 |
captionColumn | string | 否 | 维度名$caption 对应的显示列 |
captionDef | object | 否 | caption 的公式或方言定义 |
keyCaption | string | 否 | 维度主键显示名称 |
keyDescription | string | 否 | 维度主键描述 |
type | string | 否 | 维度类型,如 NORMAL、DAY、DATETIME、DICT、BOOL、DOUBLE、INTEGER |
properties | array | 否 | 维度属性列表 |
dimensions | array | 否 | 嵌套子维度列表 |
alias | string | 否 | 维度别名,用于缩短引用路径 |
joinTo | string | 否 | 兼容旧模型的关联目标字段;新模型优先使用嵌套维度结构表达层级 |
forceIndex | string | 否 | 强制索引名称 |
dimensionDataSql | function | 否 | 维度数据权限 SQL 生成函数 |
onBuilder | function | 否 | 自定义关联条件构建函数 |
memberPermission | object | 否 | 维度成员查询权限,见 2.5 |
ai | object | 否 | 维度级 AI 元数据配置 |
deprecated | boolean | 否 | 是否废弃 |
extData | object | 否 | 自定义扩展元数据 |
¹ tableName 和 viewSql 通常二选一。
2.2 captionDef
captionDef 用于定义 维度名$caption 的来源。它适合处理 JSON 翻译字段、跨方言表达式或不能直接用单列表达的显示值。
{
name: 'product',
tableName: 'product_template',
foreignKey: 'product_id',
primaryKey: 'id',
captionDef: {
column: 'name',
dialectFormulaDef: {
postgresql: {
builder: (alias) => `${alias}.name ->> 'en_US'`
}
},
formulaDef: {
builder: (alias) => `${alias}.name`
}
}
}优先级为:captionDef.dialectFormulaDef > captionDef.formulaDef > captionDef.column > 外层 captionColumn。
2.3 嵌套维度引用
嵌套维度使用 . 表示建模路径,使用 $ 表示属性访问。
| 语法 | 说明 |
|---|---|
product$caption | 访问一级维度 product 的显示值 |
product.category$caption | 访问 product -> category 的显示值 |
product.category.group$caption | 访问三级嵌套维度的显示值 |
productCategory$caption | 使用 TM 中定义的 alias 访问维度 |
响应列名中,嵌套维度路径里的 . 通常转为 _,例如 product.category$caption 对应 product_category$caption。面向 DSL 调用方时,应以当前 QM 暴露的最终字段名为准。
2.4 父子维度属性
父子维度用于组织架构、品类树等层级结构。
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
closureTableName | string | 是 | 闭包表名称 |
closureTableSchema | string | 否 | 闭包表 schema |
parentKey | string | 是 | 闭包表祖先列 |
childKey | string | 是 | 闭包表后代列 |
父子维度配合 DSL 的 childrenOf、descendantsOf、selfAndDescendantsOf 等操作符使用。
2.5 维度成员权限
维度可声明 memberPermission,控制 synthetic member-QM 或成员查询时可见的成员字段、强制过滤、排序和层级操作范围。QM 可通过 memberPermissions[] 对指定维度做覆盖。
{
name: 'product',
tableName: 'dim_product',
foreignKey: 'product_key',
primaryKey: 'product_key',
captionColumn: 'product_name',
properties: [
{ column: 'brand', caption: '品牌' }
],
memberPermission: {
patch: {
visibleColumns: ['id', 'caption', 'brand'],
forcedSlice: [
{ field: 'enabled', op: '=', value: true }
],
forcedOrderBy: [{ field: 'caption', dir: 'ASC' }],
hierarchyEnabled: true,
allowedHierarchyOps: ['childrenOf', 'descendantsOf']
},
queryBuilder: (context) => {
context.query.and(context.member.enabled, true);
}
}
}3. 属性定义
properties 描述非聚合字段,通常用于明细字段、枚举字段、状态字段、日期字段等。
properties: [
{
column: 'order_status',
caption: '订单状态',
description: '订单生命周期状态',
type: 'STRING'
}
]| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
column | string | 是 | 物理列名 |
name | string | 否 | 语义字段名,默认由 column 转换得到 |
alias | string | 否 | 字段别名 |
caption | string | 否 | 显示名称 |
description | string | 否 | 字段语义描述 |
type | string | 否 | 数据类型 |
format | string | 否 | 格式化模板 |
dictRef | string/object | 否 | 字典引用 |
aggregationFormula | string | 否 | 自定义聚合表达式,供特定聚合场景使用 |
formulaDef | object | 否 | 计算字段定义 |
dialectFormulaDef | object | 否 | 方言专属计算字段定义,优先级高于 formulaDef |
dimensions | number | 否 | 向量字段维度,type: 'VECTOR' 时使用 |
metric | string | 否 | 向量距离度量,如 cosine、euclidean、dotProduct |
semanticScaleFactor | number/string | 否 | 语义缩放因子,例如物理分转换为语义元 |
semanticUnit | string | 否 | 缩放后的语义单位,如 yuan |
semanticUnitLabel | string | 否 | 语义单位显示名,如 元 |
ai | object | 否 | AI 元数据配置 |
deprecated | boolean | 否 | 是否废弃 |
extData | object | 否 | 自定义扩展元数据 |
4. 指标定义
measures 描述可聚合字段。aggregation 是默认聚合方式,查询时可以在 DSL 中覆盖。
measures: [
{
column: 'sales_amount',
caption: '销售金额',
type: 'MONEY',
aggregation: 'sum'
}
]| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
column | string | 否¹ | 物理列名 |
name | string | 否 | 指标名,默认由 column 转换得到 |
alias | string | 否 | 指标别名 |
caption | string | 否 | 显示名称 |
description | string | 否 | 指标语义描述 |
type | string | 否 | 数据类型 |
aggregation | string | 是 | 默认聚合方式 |
formulaDef | object | 否 | 计算指标定义 |
dialectFormulaDef | object | 否 | 方言专属计算指标定义,优先级高于 formulaDef |
semanticScaleFactor | number/string | 否 | 语义缩放因子,例如物理分转换为语义元 |
semanticUnit | string | 否 | 缩放后的语义单位,如 yuan |
semanticUnitLabel | string | 否 | 语义单位显示名,如 元 |
ai | object | 否 | AI 元数据配置 |
deprecated | boolean | 否 | 是否废弃 |
extData | object | 否 | 自定义扩展元数据 |
¹ count 类型指标可以不绑定具体 column。
4.1 聚合方式
| 值 | 说明 |
|---|---|
sum / SUM | 求和 |
avg / AVG | 平均值 |
count / COUNT | 计数 |
count_distinct / COUNT_DISTINCT | 去重计数 |
max / MAX | 最大值 |
min / MIN | 最小值 |
GROUP_CONCAT | 字符串聚合,使用前应验证目标数据库方言 |
STDDEV_POP | 总体标准差 |
STDDEV_SAMP | 样本标准差 |
VAR_POP | 总体方差 |
VAR_SAMP | 样本方差 |
none / NONE | 不聚合 |
5. 公式与 AI 元数据
5.1 formulaDef
formulaDef 用于在 TM 中为绑定到物理列的字段或指标提供 SQL 表达式。当前 Java 引擎仍要求 TM property/measure 声明 column;如果需要不依赖单个物理列的纯计算输出,应优先在 QM column item 中使用 formula。
| 属性 | 类型 | 说明 |
|---|---|---|
builder | function | SQL 构建函数,参数通常为表别名 |
value | string | 公式表达式 |
description | string | 公式说明 |
{
name: 'amountInWan',
column: 'amount',
caption: '金额(万元)',
type: 'MONEY',
formulaDef: {
builder: (alias) => `${alias}.amount / 10000`,
description: '金额单位换算'
}
}5.2 dialectFormulaDef
dialectFormulaDef 用于为不同数据库方言提供不同 SQL 构建逻辑。它可用于属性、指标和维度 captionDef,优先级高于通用 formulaDef。
{
name: 'localizedName',
column: 'name',
caption: '本地化名称',
type: 'STRING',
dialectFormulaDef: {
postgresql: {
builder: (alias) => `${alias}.name ->> 'en_US'`
},
mysql: {
builder: (alias) => `JSON_UNQUOTE(JSON_EXTRACT(${alias}.name, '$.en_US'))`
}
},
formulaDef: {
builder: (alias) => `${alias}.name`
}
}5.3 semanticScaleFactor
semanticScaleFactor 用于声明物理存储单位和语义查询单位之间的比例。例如 ERP 系统把金额以“分”存储,对外分析希望以“元”查询,可以在物理列字段上声明缩放因子。
{
column: 'amount_cent',
name: 'amount',
caption: '金额',
type: 'MONEY',
aggregation: 'sum',
semanticScaleFactor: 100,
semanticUnit: 'yuan',
semanticUnitLabel: '元'
}该能力适用于直接绑定物理列的 property 或 measure。不要把 semanticScaleFactor 与 formulaDef / dialectFormulaDef 混用;复杂换算应使用公式字段显式建模。
5.4 ai
ai 用于补充面向 LLM 的字段说明。
| 属性 | 类型 | 说明 |
|---|---|---|
enabled | boolean | 是否向 AI 上下文暴露 |
prompt | string | 供 AI 使用的语义提示 |
levels | number[] | 字段可见或推荐等级 |
6. 数据类型
| 类型 | 别名 | 说明 | 常见用途 |
|---|---|---|---|
STRING | - | 短字符串 | 编码、ID、名称 |
TEXT | VARCHAR、CHAR、CLOB | 文本 | 长文本、备注 |
INTEGER | - | 整数 | 计数、枚举 |
BIGINT | LONG | 长整数 | 大数值主键 |
MONEY | - | 金额小数 | 金额、价格 |
NUMBER | DECIMAL、NUMERIC、DOUBLE、FLOAT | 数值小数 | 比率、数量、通用数值 |
DATETIME | TIMESTAMP、TIME | 日期时间 | 时间戳 |
DAY | DATE | 日期 | yyyy-MM-dd |
BOOL | Boolean | 布尔值 | 是/否标志 |
DICT | - | 字典值 | 枚举编码 |
VECTOR | - | 向量 | 语义检索字段 |
VECTOR、mongo、预聚合等高级能力依赖具体引擎或扩展模块;公开语法中可以建模,但上线前应在目标运行时验证。预聚合的匹配、刷新和运行边界见 预聚合能力参考。
7. 命名规则
| 对象 | 建议命名 | 示例 |
|---|---|---|
| TM 文件 | {ModelName}.tm | FactSalesModel.tm |
TM name | PascalCase | FactSalesModel |
字段 name | camelCase | salesAmount |
JDBC column | snake_case | sales_amount |
| 维度属性引用 | $ 分隔 | customer$caption |
| 嵌套维度建模路径 | . 导航 | product.category$caption |
JDBC 字段名通常由 snake_case 自动转为 camelCase,例如 order_count 转为 orderCount。当 column 自动转换后的名称已经符合期望时,可以省略 name;只有在 _id、缩写列名或需要自定义语义名时再显式声明 name。
