引擎层:存储、索引与执行
引擎做四件事:记住定义、存对象、回答查询、执行 Action。当前值 = 数据源的值 + Semantic 里的改动。

本课目标
读完这一课,你将能够
- 说出引擎层做的四件事,并把它们对应到一条数据的旅程
- 解释「当前值 = 数据源的值 + Semantic 里的改动」,判断一次同步之后会读到什么
- 记住读写的几个上限,并用它们反推设计
引擎做四件事
上一课写下的是定义。让定义活起来的是引擎层。不管内部怎么实现,它做的事就四件,顺序也是一条数据的旅程:
- 01记住定义有哪些对象类型、关系、Action
- 02存对象数据源的值,加上 Semantic 里的改动
- 03回答查询搜索、筛选、聚合、沿关系走
- 04执行 Action先校验,再一个事务写入,留记录
数据源只读地进来,落成对象;人和智能体通过 Action 改它;读的人拿到的,永远是合并之后的当前值。数据源一变,对象就要跟着变,把数据源搬进对象、让它能被快速查询的这一步,通常叫索引。
当前值 = 数据源的值 + 改动
同一个属性有两个来源:数据源同步来的值,和人或智能体通过 Action 改的值。引擎把两层叠起来读,改动在上面。看一张工单的 status:
| 数据源那一层 | 你读到的当前值 | |
|---|---|---|
| 第一次同步 | status = released | released |
有人执行 hold-work-order | 未配 writeback 时仍是 released | paused;overridden 记着被盖住的数据源值 released |
数据源再同步:status = running,goodQty 更新 | status = running | status 仍是 paused,人改的不被冲掉;goodQty 跟着数据源更新 |
未配 writeback 时,改动只落在语义层。读对象时,overridden 提示被改动盖住的属性,sourceGone 表示源头已无此行,rev 每改一次加 1。写入带 ifRev 可防止并发覆盖。
ifRev 用在两处:旧写法的 aidc semantic act … --if-rev N,以及开发者直接写数据。对不上就返回 409 rev_mismatch,刷新之后再改。规则式的 Action(例如 hold-work-order)没有 ifRev:它在执行的那一刻判断提交条件,所以两个班组长同时暂停同一张工单,后一个会被条件拦下。
修改语义层不会自动修改 ERP。只有给 Action 配 writeback webhook,才会调用源系统。下一次同步不会冲掉语义层的改动。
读:对象集变成一条 SQL
引擎把对象集编译成一条 SQL,在当前值上执行。符合条件的 Object Type 才有同名 Postgres 视图。部门级类型、受 Markings 或安全策略保护的类型、名字超过 63 字节的类型、没有存储属性的类型不建视图。可用 SQL Console 或 psql 查询已有视图。
例如统计一条产线上各种状态的工单数,就是一条普通的 SELECT:
SELECT status, count(*) AS n
FROM "WorkOrder"
WHERE "lineCode" = 'L1'
GROUP BY status;
派生属性是读时算出来的,不进 SQL 视图,也不能用来过滤或排序。要按它筛选时,先想想它是不是该变成一个存下来的属性。
查询也有规则:搜索条件最多嵌套三层;按属性分组的聚合,缺省最多返回 10,000 组。临时对象集用来把一次查询的结果交给下一次调用,24 小时后过期。
数据接入也是引擎的一部分。连接 SDK 的发布端只读源系统。绑定写在 Object Type 的 datasources 中,也可用 aidc semantic datasource set 配置。平台保存定义后先全量同步,再只同步变化。
写:一个事务,几个上限
新建 Object Type 缺省只能经 Action 改。开发者可直接编辑明确设了 editsConfiguration.onlyAllowPrivilegedEdits: false 的类型。执行 Action 时,引擎先校验参数和提交条件,再在一个事务里写入改动和记录。设计时要记住几个上限:
批量执行先校验全部请求。一个不通过,就全部不写。带 writeback webhook 的 Action 不接受 applyBatch。
这些上限逼你把问题写小:先用条件缩小对象集再取回,分页取而不是一次全拿,大批量的修改拆成几次 Action。
引擎在里面跑,人和程序要从外面进来。下一节看进来的四个入口。
要点
- 引擎做四件事:记住定义、存对象、回答查询、执行 Action。
- 当前值 = 数据源的值 + 语义层改动。同步不冲掉改动;配置 writeback webhook 的 Action 可改源系统。
- 对象集被编译成一条 SQL;派生属性读时计算,不能过滤或排序。
- Action 先校验再在一个事务里写入,一次最多改 10,000 个对象。批量最多 20 个请求;带 writeback webhook 的 Action 不支持批量。
练一练
推演一次同步
用示例工厂的一张工单推演一遍,写出每一步读到的当前值。
画出数据源那一层和改动那一层。工单进来时 status = released、goodQty 为空;有人执行 hold-work-order。当前值是什么?overridden 里有什么?
数据源变成 status = running、goodQty 有了数。当前值里的两个属性各是什么?为什么不一样?
月底要给 12,000 张工单批量改负责人。用上面的上限,写出你会怎么拆。
小测
选一个答案,马上看解析。
Q1有人用 Action 把某张工单的 status 改成 paused,数据源随后同步来 status = running。读到的 status 是?
同步只更新数据源自己那一层,人改过的属性以改动为准。数据源的新值会出现在 overridden 里。
Q2一个 Action 想一次改 12,000 个对象,会怎样?
一次最多改 10,000 个对象,超过就不能一次做。Action 是一个事务,不会只成功一半。
Q3为什么不能按派生属性排序?
三跳是另一条上限,只读也是事实,但都不是原因。原因是它没有存下来的值。