返回正文目录

查询工具

dataset.query_model 是核心数据查询工具,支持复杂的过滤、排序、分组和聚合操作。

它面向单个 Query Model。需要跨模型 Join/Union、derived 或多阶段计划时使用 dataset.compose_script;需要查看编译计划或 SQL/物理映射时使用 dataset.explain_query。这些工具仍受当前 namespace、模型权限和运行实例 schema 限制。

不要把原始 SQL、自由 CTE 或 fieldAccess、deniedColumns、systemSlice 等内部治理字段作为普通 MCP 输入。DSL_CTE、Pivot、timeWindow 和 calculatedFields 的可用性以当前 tools/list、capabilities 和 schema 为准。

基本信息

参数说明

参数 类型 必填 说明
model string ✅ 查询模型名称
payload object ✅ 查询参数对象
mode string ❌ 执行模式:execute(默认)或 validate

payload 参数详解

参数 类型 说明
columns array 返回的列,支持内联聚合
slice array 过滤条件
orderBy array 排序规则
groupBy array 分组字段(通常自动处理)
calculatedFields array 计算字段定义
timeWindow object 时间窗口分析,支持同比、环比、累计、滚动窗口
pivot object 多维透视分析,支持行轴、列轴、指标、小计、总计
start number 起始行号(从 0 开始)
limit number 返回记录数
returnTotal boolean 是否返回总数

pivot 与 columns 互斥,pivot 与 timeWindow 互斥。需要透视表时使用 pivot;需要同比、环比、滚动窗口时使用 timeWindow。

字段使用规则

维度字段

维度字段返回两个变体:

{
  "columns": ["customer$caption", "salesDate$caption"],
  "slice": [
    {"field": "customer$id", "op": "=", "value": 1001}
  ]
}

父子维度

层级结构维度支持 $hierarchy$ 视角:

{
  "slice": [
    {"field": "team$hierarchy$id", "op": "=", "value": "T001"}
  ]
}

属性和度量字段

直接使用返回的字段名:

{
  "columns": ["orderNo", "totalAmount", "quantity"]
}

过滤条件 (slice)

支持的操作符

操作符 说明 示例
= 等于 {"field": "status", "op": "=", "value": 1}
!=, <> 不等于 {"field": "status", "op": "!=", "value": 0}
>, >=, <, <= 比较 {"field": "amount", "op": ">", "value": 100}
like 模糊匹配 {"field": "name", "op": "like", "value": "张"}
left_like 前缀匹配 {"field": "code", "op": "left_like", "value": "ORD"}
in 包含 {"field": "type", "op": "in", "value": [1, 2, 3]}
not in 不包含 {"field": "type", "op": "not in", "value": [0]}
is null 为空 {"field": "remark", "op": "is null"}
is not null 不为空 {"field": "remark", "op": "is not null"}
[], [), (), (] 区间 {"field": "date", "op": "[)", "value": ["2025-01-01", "2025-12-31"]}

过滤示例

{
  "slice": [
    {"field": "salesDate$id", "op": "[)", "value": ["20250101", "20251231"]},
    {"field": "customer$caption", "op": "like", "value": "张三"},
    {"field": "customerType", "op": "in", "value": [10, 20, 30]},
    {"field": "remark", "op": "is not null"}
  ]
}

聚合查询

内联聚合表达式(推荐)

在 columns 中直接写聚合,系统自动处理 groupBy:

{
  "columns": [
    "product$categoryName",
    "sum(salesAmount) as totalSales",
    "count(orderId) as orderCount",
    "avg(unitPrice) as avgPrice"
  ]
}

支持的聚合函数:sum, avg, count, max, min

计算字段 (calculatedFields)

需要复杂表达式或指定 agg 时使用:

{
  "calculatedFields": [
    {
      "name": "netAmount",
      "expression": "salesAmount - discountAmount",
      "agg": "SUM"
    },
    {
      "name": "taxAmount",
      "expression": "salesAmount * 0.13",
      "agg": "SUM"
    }
  ],
  "columns": ["customer$caption", "netAmount", "taxAmount"]
}

时间窗口 (timeWindow)

timeWindow 用于表达同比、环比、年初至今、月初至今和滚动窗口等分析。它会基于 targetMetrics 自动追加后缀列。

{
  "model": "FactSalesQueryModel",
  "payload": {
    "columns": ["salesDate$id", "salesAmount"],
    "groupBy": ["salesDate$id"],
    "timeWindow": {
      "field": "salesDate$id",
      "grain": "month",
      "comparison": "yoy",
      "value": ["2025-01-01", "2026-01-01"],
      "targetMetrics": ["salesAmount"]
    }
  }
}

同比、环比、周环比会追加:

ytd / mtd / rolling_7d / rolling_30d / rolling_90d 会分别追加累计或滚动窗口后缀。完整规则见 Compose Query DSL 手册。

多维透视 (pivot)

pivot 用于生成透视表结果。开启后不要再传 columns。

{
  "model": "FactSalesQueryModel",
  "payload": {
    "pivot": {
      "rows": ["region$caption"],
      "columns": ["salesDate$month"],
      "metrics": ["salesAmount"],
      "options": {
        "rowSubtotals": true,
        "columnSubtotals": true,
        "grandTotal": true
      },
      "outputFormat": "grid"
    },
    "slice": [
      { "field": "salesDate$id", "op": "[)", "value": ["2025-01-01", "2026-01-01"] }
    ]
  }
}

Pivot 支持受限派生指标:

{
  "pivot": {
    "rows": [
      "region$caption",
      "city$caption"
    ],
    "columns": ["salesDate$month"],
    "metrics": [
      "salesAmount",
      {
        "name": "salesParentShare",
        "type": "parentShare",
        "of": "salesAmount",
        "axis": "rows",
        "level": "city$caption",
        "parentLevel": "region$caption"
      },
      {
        "name": "salesVsFirstMonth",
        "type": "baselineRatio",
        "of": "salesAmount",
        "axis": "columns",
        "baseline": "first"
      }
    ],
    "outputFormat": "grid"
  }
}

parentShare 当前用于 rows 父级占比,不能与 hierarchyMode=tree、cascade TopN、轴级 having / orderBy / limit 混用;baselineRatio 当前用于 columns 首项或末项基准比值,不能与 tree/cascade/having/orderBy/limit 混用。超出边界时移除派生指标返回普通 pivot,不要生成隐藏函数。完整字段见 Pivot 多维透视。

排序 (orderBy)

{
  "orderBy": [
    {"field": "totalSales", "dir": "DESC"},
    {"field": "customer$caption", "dir": "ASC"}
  ]
}

注意:聚合查询时,orderBy 字段必须在 columns 中出现。

分页

{
  "start": 0,
  "limit": 30,
  "returnTotal": true
}

完整示例

基础查询

{
  "model": "FactSalesQueryModel",
  "payload": {
    "columns": ["orderNo", "customer$caption", "salesDate$caption", "totalAmount"],
    "slice": [
      {"field": "salesDate$id", "op": "[)", "value": ["20250101", "20251231"]}
    ],
    "orderBy": [{"field": "salesDate$id", "dir": "DESC"}],
    "start": 0,
    "limit": 30
  }
}

聚合查询

{
  "model": "FactSalesQueryModel",
  "payload": {
    "columns": [
      "salesDate$caption",
      "sum(totalAmount) as totalSales",
      "count(orderId) as orderCount"
    ],
    "slice": [
      {"field": "salesDate$id", "op": "[)", "value": ["20250101", "20251231"]}
    ],
    "orderBy": [{"field": "totalSales", "dir": "DESC"}],
    "start": 0,
    "limit": 50
  }
}

MCP 协议调用

{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "tools/call",
  "params": {
    "name": "dataset.query_model",
    "arguments": {
      "model": "FactSalesQueryModel",
      "payload": {
        "columns": ["customer$caption", "sum(totalAmount) as total"],
        "limit": 10
      }
    }
  }
}

响应格式

标准响应

{
  "success": true,
  "data": {
    "items": [
      {"customer$caption": "张三", "total": 12500.00},
      {"customer$caption": "李四", "total": 8900.00}
    ],
    "total": 156,
    "start": 0,
    "limit": 10,
    "pagination": {
      "start": 0,
      "limit": 10,
      "returned": 10,
      "totalCount": 156,
      "hasMore": true,
      "rangeDescription": "显示第 1-10 条,共 156 条"
    }
  }
}

大数据自动截断

当 MCP 查询返回的数据量过大时(单元格数超过阈值),系统会自动截断结果并提供完整数据的访问链接,避免大量数据占用 LLM 的上下文窗口。

触发条件

截断响应格式

{
  "success": true,
  "data": {
    "items": [
      // ... 截断后的 100 行数据
    ],
    "total": 50000,
    "truncationInfo": {
      "truncated": true,
      "originalRowCount": 50000,
      "truncatedRowCount": 100,
      "columnCount": 15,
      "cellCount": 750000,
      "message": "数据量较大(50000 行 × 15 列 = 750000 单元格),已自动截断为 100 行。",
      "viewerUrl": "http://localhost:8080/data-viewer/view/abc123def456",
      "apiUrl": "http://localhost:8080/data-viewer/api/query/abc123def456/data",
      "hint": "您可以访问上述链接查看完整数据,或通过 API 分页获取(参数:start, limit)"
    }
  }
}

字段说明

字段 类型 说明
truncated boolean 是否发生了截断
originalRowCount number 原始数据行数
truncatedRowCount number 截断后保留的行数
columnCount number 列数
cellCount number 总单元格数
message string 截断说明信息
viewerUrl string 完整数据的浏览器查看链接
apiUrl string 完整数据的 API 查询链接
hint string 使用提示

LLM 处理建议

当检测到 truncationInfo.truncated = true 时,LLM 应该:

  1. 告知用户数据被截断:解释原因(数据量过大)
  2. 展示样本数据:使用截断后的 100 行作为样本
  3. 提供访问链接:引导用户通过链接查看完整数据
  4. 说明分页选项:如需编程访问,可使用 API 分页获取

示例回复:

查询返回了 50,000 行数据(共 750,000 个单元格),数据量较大。我这里展示前 100 行样本数据供您参考:

[展示表格...]

完整数据请访问:数据浏览器

如需通过 API 分页获取,可使用:/data-viewer/api/query/abc123def456/data?start=0&limit=100

配置阈值

在 application.yml 中调整截断参数:

foggy:
  data-viewer:
    thresholds:
      # 单元格阈值(行 × 列)
      cell-threshold-for-truncation: 10000
      # 截断后保留的行数
      truncated-row-limit: 100

最佳实践

  1. 展示用 $caption,过滤用 $id
  2. 简单聚合用内联表达式:sum(amount) as total
  3. 复杂计算用 calculatedFields
  4. 大数据量使用分页:设置合理的 limit
  5. 添加过滤条件:避免全表扫描
  6. 同比 / 环比使用 timeWindow:不要手写多段日期 SQL
  7. 透视表使用 pivot:不要同时传 columns 或 timeWindow
  8. Pivot 派生指标使用白名单:当前只使用 parentShare / baselineRatio,不要生成 ROLLUP_TO / CELL_AT / AXIS_MEMBER

下一步