查询工具
dataset.query_model 是核心数据查询工具,支持复杂的过滤、排序、分组和聚合操作。
基本信息
- 工具名称:
dataset.query_model - 分类: 数据查询
- 权限: Admin, Analyst
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
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。
字段使用规则
维度字段
维度字段返回两个变体:
xxx$id- 用于精确查询和过滤xxx$caption- 用于展示名称
{
"columns": ["customer$caption", "salesDate$caption"],
"slice": [
{"field": "customer$id", "op": "=", "value": 1001}
]
}父子维度
层级结构维度支持 $hierarchy$ 视角:
xxx$id- 精确匹配该节点xxx$hierarchy$id- 匹配该节点及所有后代
{
"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"]
}
}
}同比、环比、周环比会追加:
salesAmount__prior:前期值salesAmount__diff:差值salesAmount__ratio:增长率
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 的上下文窗口。
触发条件
- 查询来源:仅对 MCP 工具调用生效
- 数据量阈值:单元格数(行数 × 列数)超过 10000(可配置)
- 截断行数:保留前 100 行返回给 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 应该:
- 告知用户数据被截断:解释原因(数据量过大)
- 展示样本数据:使用截断后的 100 行作为样本
- 提供访问链接:引导用户通过链接查看完整数据
- 说明分页选项:如需编程访问,可使用 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最佳实践
- 展示用
$caption,过滤用$id - 简单聚合用内联表达式:
sum(amount) as total - 复杂计算用
calculatedFields - 大数据量使用分页:设置合理的
limit - 添加过滤条件:避免全表扫描
- 同比 / 环比使用
timeWindow:不要手写多段日期 SQL - 透视表使用
pivot:不要同时传columns或timeWindow - Pivot 派生指标使用白名单:当前只使用
parentShare/baselineRatio,不要生成ROLLUP_TO/CELL_AT/AXIS_MEMBER
下一步
- 元数据工具 - 获取模型字段信息
- Compose Query DSL 手册 - timeWindow、CTE、派生、Join、Union
- Pivot 多维透视 - 透视表 DSL
- 自然语言查询 - 智能数据查询
- 工具概述 - 返回工具列表