Skip to content

复杂数据查询

本章节详细介绍基于数据模型处理器和 Query DSL 两种数据查询方式。建议在阅读前学习关系型数据库基础知识,了解 SQL 语法,可以编写基本的 SQL 语句。

使用 Model 处理器查询

数据模型处理器 Find, Get, Paginate, UpdateWhere, DeleteWhere, DestroyWhere 均支持传入查询参数 Object QueryParam,对读取记录范围进行限定。

Object QueryParam:

JSON 描述:

json
{
  "select": ["id", "name", "mobile", "status"],
  "withs": {
    "manu": { "query": ["name", "short_name", "status"] },
    "addresses": {}
  },
  "wheres": [
    { "column": "status", "value": "enabled" },
    { "rel": "manu", "column": "status", "value": "enabled" },
    {
      "wheres": [
        { "column": "name", "value": "%张三%", "op": "like" },
        {
          "method": "orwhere",
          "column": "name",
          "value": "%李四%",
          "op": "like"
        }
      ]
    }
  ],
  "orders": [
    { "column": "id", "option": "desc" },
    { "rel": "manu", "column": "name" }
  ],
  "limit": 2
}

引擎解析后的 SQL:

sql
SELECT
  `user`.`id`,`user`.`name`,`user`.`mobile`,`user`.`status`,
  `user_manu`.`name` AS `user_manu_name`,
  `user_manu`.`short_name` AS `user_manu_short_name` ,
  `user_manu`.`status` AS `user_manu_status`
FROM `user` AS `user`
LEFT JOIN `manu` AS `user_manu` ON `user_manu`.`id` = `user`.`manu_id`
WHERE  `user`.`status` = 'enabled'
AND `user_manu`.`status` = 'enabled'
AND (
   `user`.`name` like '%张三%' OR `user`.`name` like '%李四%'
)
ORDER BY `user`.`id` desc, `user_manu`.`name` asc
LIMIT 2

数据结构说明:

QueryParam

字段类型说明必填项
selectArray<String>选择字段清单
wheresArray<Object Where>查询条件
ordersArray<Object Order>排序条件
limitInteger返回记录条目
pageInteger当前页码
pagesizeInteger每页显示记录数量
withs[key:String]:Object QueryParam读取关联模型

Object Where

字段类型说明必填项
relString如按关联模型的字段查询,则填写关联模型名称
columnString字段名称
methodString查询方法 where,orwhere 默认为 where
opString匹配关系 eq,like,in,gt 等 默认为 eq
valueAny匹配数值
wheresArray<Object Where>分组查询
查询方法说明
whereWHERE 字段 = 数值, WHERE 字段 >= 数值
orwhere... OR WHERE 字段 = 数值
匹配关系说明
eq默认值 等于 WHERE 字段 = 数值
like匹配 WHERE 字段 like 数值
match匹配 WHERE 字段 全文检索 数值
gt大于 WHERE 字段 > 数值
ge大于等于 WHERE 字段 >= 数值
lt小于 WHERE 字段 < 数值
le小于等于 WHERE 字段 <= 数值
null为空 WHERE 字段 IS NULL
notnull不为空 WHERE 字段 IS NOT NULL
in列表包含 WHERE 字段 IN (数值...)
ne不等于匹配值

Object Order

字段类型说明必填项
relString如按关联模型的字段排序,则填写关联模型名称
columnString字段名称
optionString排序方式, desc, asc, 默认为 asc

使用 Query DSL 查询

Query DSL 可以在数据流中使用,一般用于数据分析统计等更为复杂的场景。

对数据表 service (见下表)分析, 统计各行业最高分。

idindustriescityscorecreated_atupdated_at
1["旅游", "教育"]北京992021-10-03 13:40:52NULL
2["旅游", "教育"]上海682021-10-03 13:40:52NULL
3["旅游", "教育"]北京922021-10-03 13:40:52NULL
4["旅游", "教育"]上海872021-10-03 13:40:52NULL
5["旅游", "教育"]北京712021-10-03 13:46:06NULL

Query DSL 示例:

JSON 描述:

json
{
  "comment": "统计各行业最高分",
  "select": ["industries@", "city", ":MAX(score) as high_score"],
  "from": "service",
  "wheres": [
    { ":created_at": "创建时间", ">=": "2021-01-01" },
    { ":created_at": "创建时间", "<=": "{'2021-12-31'}" },
    { ":updated_at": "更新时间", "is": "null" },
    {
      "wheres": [
        { ":type": "类型", "=": 1 },
        { "or:type": "或类型", "=": 2 }
      ]
    }
  ],
  "orders": "high_score desc",
  "limit": 100,
  "groups": ["industries@", "city"]
}

引擎解析后的 SQL语句 为 (MySQL 8):

sql

SELECT `@industries`.`industries`,`city`, MAX(`score`) AS `high_score`
FROM `service`
JOIN JSON_TABLE(`service`.`industries`, '$[*]' columns (`industries` varchar(50) path '$') ) as `@industries`
WHERE `created_at` >= '2021-01-01'
  AND `created_at` <= '2021-12-31'
  AND `updated_at` IS NULL
  AND ( `type` = 1 OR `type` = 2)
GROUP BY `@industries`.`industries`, `city`
ORDER BY `high_score` DESC

返回结果:

industriescityhigh_score
旅游北京99
教育北京99
旅游上海87
教育上海87

在 Flow 中使用

在数据流中,可以使用 {{$in}}?:$in 接收参数, {{$res}}?:$res 引用节点查询结果。

提示:在数据流中通过 {{$xxx}} ?:$xxx 使用变量写法等效。

使用模型处理器

json
{
  "label": "查询最新数据",
  "version": "1.0.0",
  "description": "查询系统最新数据",
  "nodes": [
    {
      "name": "宠物",
      "process": "models.pet.Get",
      "args": [
        {
          "select": ["id", "name", "kind", "created_at"],
          "wheres": [{ "column": "kind", "value": "{{$in.0}}" }],
          "orders": [{ "column": "created_at", "option": "desc" }],
          "limit": 10
        }
      ]
    }
  ],
  "output": "{{$res.宠物}}"
}

使用 Query DSL

json
{
  "label": "查询最新数据",
  "version": "1.0.0",
  "description": "查询系统最新数据",
  "nodes": [
    {
      "name": "宠物",
      "engine": "xiang",
      "query": {
        "select": ["id", "name", "kind", "created_at"],
        "from": "$pet",
        "wheres": [{ ":kind": "类型", "=": "?:$in.0" }],
        "orders": "created_at desc",
        "limit": 10
      }
    }
  ],
  "output": "{{$res.宠物}}"
}

在 Script 中使用

javascript
function test(id) {
  var query = new Query();
  var data = query.Get({
    name: '宠物',
    engine: 'xiang',
    query: {
      select: ['id', 'name', 'kind', 'created_at'],
      from: '$pet',
      wheres: [{ ':kind': '类型', '=': id }],
      orders: 'created_at desc',
      limit: 10
    }
  });
}

在数据表格中使用

在数据表格中,可以使用 filter 传递查询参数。查询参数通过 URL Query String 传递给数据表格接口。

指定查询参数名称:

json
{
  "name": "宠物",
  "version": "1.0.0",
  "decription": "宠物管理表格",
  "bind": { "model": "pet" },
  "apis": {},
  "columns": {},
  "filters": {
    "关键词": {
      "label": "关键词",
      "bind": "where.name.match",
      "input": { "type": "input", "props": { "placeholder": "请输入关键词" } }
    }
  },
  "list": {
      "filters": ["关键词"],
      ...
  },
  "edit": {}
}

在点击界面搜索按钮时,系统向表格 search API 请求数据,并传入 bind 中声明的参数名和用户填写数值:

bash
GET /api/xiang/table/pet?where.name.match=xxx