快速接入

以下包名和接口遵循当前 LogicForm V2 开发契约。

一次执行需要什么

调用 Logicform.execute(logicform, options) 至少需要四类输入:

  1. 一份 version >= 2.0 的 LogicForm;
  2. LogicForm 引用的逻辑 Schema;
  3. Schema 到物理数据源的 Mapping;
  4. Mapping 引用的数据库连接。

1. 定义 Schema

const schemas = {
  sales: {
    id: 'sales',
    name: '销售明细',
    type: 'event',
    properties: [
      { id: 'order_id', name: '订单号', type: 'ID' },
      { id: 'order_date', name: '日期', type: 'timestamp', granularity: 'day' },
      { id: 'store_name', name: '门店', type: 'category' },
      { id: 'amount', name: '销售额', type: 'currency' },
    ],
  },
};

Schema 描述业务语义,不保存数据库连接、表名或方言。property.id 是默认物理字段名,property.name 是推荐给 LogicForm 使用的业务名称。

2. 定义物理 Mapping

import { SchemaMappingRegistry } from 'semanticdb-v2';

const schemaMappings = new SchemaMappingRegistry([
  {
    id: 'sales-detail',
    schemaId: 'sales',
    connectionId: 'analytics',
    source: 'analytics.sales_detail',
    freshness: { mode: 'ttl', ttlSeconds: 300 },
  },
]);

常用字段:

字段必填说明
id同一 Schema 有多个 Mapping 时使用的稳定标识
schemaId对应 schema.id
connectionId对应连接的 id
source物理表或稳定的数据源标识
sourceSql受信任的派生表 SQL
properties逻辑 Property 到物理列的映射,同时也是该 Mapping 的字段白名单
predMappings把特定指标与条件映射到预计算物理列
priority多个候选都覆盖请求时的优先级,数值越大优先级越高
freshness查询缓存的新鲜度策略

未配置 properties 时,Property 默认使用 property.id 作为物理列名。

3. 提供连接

const connections = [
  {
    id: 'analytics',
    kind: 'clickhouse',
    url: 'http://localhost:8123',
    username: 'default',
    password: process.env.CLICKHOUSE_PASSWORD,
    database: 'analytics',
  },
];

内置连接类型包括:

  • mysql
  • doris
  • starrocks
  • postgresql
  • clickhouse
  • snowflake
  • oracle

每个连接必须有非空且唯一的 id。一条 LogicForm 的所有物理依赖必须能路由到同一种 Provider;不能在一次查询中跨不同数据库连接做隐式联邦计算。

4. 执行 LogicForm

import { Logicform } from 'semanticdb-v2';

const response = await Logicform.execute(
  {
    version: '2.0',
    schema: 'sales',
    query: {
      日期: { granularity: 'month', offset: -1 },
    },
    groupby: [
      { pred: '门店', name: '门店' },
    ],
    preds: [
      { operator: '$sum', pred: '销售额', name: '销售额' },
      { operator: '$countDistinct', pred: '订单号', name: '订单数' },
    ],
    sort: { 销售额: -1 },
    limit: 20,
  },
  {
    schemas,
    schemaMappings,
    connections,
    locale: 'zh-CN',
  },
);

成功时:

if (!('errorCode' in response)) {
  console.log(response.result);
  console.log(response.schema);
  console.log(response.normedLogicform);
  console.log(response.sqls);
  console.log(response.lineage);
}

ExecuteOptions 一览

字段必填说明
schemasschema.id 到 Schema Draft 的字典
schemaMappingsSchemaMappingRegistry 实例
connections数据库连接数组
semanticTypes自定义 SemanticTypeRegistry;省略时只使用内置类型
operators自定义 OperatorRegistry;省略时只使用内置 Operator 和插件 Operator
plugins本次执行启用的外部插件
locale自动生成指标名的语言,默认 zh-CN
permissionsSchema、行和列权限
customFunctions兼容旧系统的动态复合指标定义
customFunctionConfig传递给动态复合指标回调的配置
cache调用方持有的 Query Cache 与 namespace
onProgress执行进度回调
signal用于取消执行的 AbortSignal

连接和 Registry 生命周期

  • SchemaMappingRegistrySemanticTypeRegistryOperatorRegistry、插件定义和 Query Cache 都建议在应用启动时创建并跨请求复用。
  • 连接配置由调用方提供,SemanticDB 按 connection.id 复用内部连接。
  • 应用关闭时调用 await Logicform.close() 关闭 SemanticDB 管理的数据库连接。
  • 调用方注入的 Query Cache 不会被 Logicform.close() 自动关闭,应按缓存实现自己的生命周期关闭。

权限示例

permissions: {
  sales: {
    rowPermissions: { 区域: { $in: ['华东', '华南'] } },
    columnPermissions: {
      whitelist: ['订单号', '日期', '门店', '销售额'],
    },
  },
}

传入 permissions 时,它的 Schema key 同时构成 Schema allowlist。行权限会与用户 Query 合取,列权限限制可查询和可输出的 Property;权限条件不会被用户条件覆盖。