新建属性/链接时开启动态计算,则为计算属性/链接,属性/链接值不落库,查询时基于其他属性/链接计算值。常用于冗余头表字段、统计行表数据、联查主数据信息等。计算属性/链接可能会使查询数据变慢,请合理使用
如果只是简单地查询链接对象的属性/链接,用于UX页面展示,可使用领域模型的启用联查功能。开启后,UX数据源可直接读取单选链接目标对象的属性/链接,详见:【领域模型】使用文档 - 模型视图
如果有很多计算类似报表需求,建议还是计算后把结果写入对象。如果是少量计算,但计算较为复杂,例如:包含多个if…else表达式与复杂计算公式,可以使用属性/链接的数据重写功能,详见:数据重写
计算属性/链接主要定义一个赋值给属性/链接的表达式(DeepQL语句),即property := (expr)
、link := (expr)
中:=
的右边部分,针对当前数据,不同于查询器中运行的完整查询语句。提供UI配置、DeepQL语句等编辑方式,便于定义表达式
如果UI配置不能满足计算逻辑,则使用DeepQL语句。可在全局配置->DDL日志中查看UI配置下计算属性/链接对应的DeepQL语句,即using (expr)
中的表达式,并基于此进行修改
编辑方式包括:UI模式、QL模式
UI模式:通过UI配置定义表达式,用于单个属性的查询、聚合,以及单个链接的计数
配置 |
说明 |
---|---|
引用属性 |
从当前对象出发选择属性/链接,可通过链接级联查询到其他对象的属性/链接 |
计算类型 |
引用属性为属性时包括:查询、聚合;为链接时包括:计数 |
聚合类型 |
计算类型为聚合时选择聚合类型,支持常用计算,包括:非空计数count、去重计数count distinct、求和sum、平均值math::mean、最小值min、最大值max、拼接(可设置分隔符)等 |
过滤条件 |
新建计算属性后,可在属性属性栏中设置过滤条件。过滤条件对引用属性最后一层对象进行过滤,引用属性为属性时,对查询属性的所属对象进行过滤;为链接时,对查询链接的目标对象进行过滤 |
QL模式:通过DeepQL语句定义表达式,用于多个属性的四则运算、按条件取值等复杂计算逻辑
编辑方式包括:级联模式、联查模式、QL模式
级联模式:通过UI配置定义表达式,用于单个链接的查询
配置 |
说明 |
---|---|
引用链接 |
从当前对象出发选择链接,可通过链接级联查询到其他对象的链接 |
计算类型 |
仅支持查询 |
过滤条件 |
新建计算链接后,可在链接属性栏中设置过滤条件,过滤条件对引用链接进行过滤 |
联查模式:通过UI配置定义表达式,使用当前对象的文本属性与查询对象的业务主键进行匹配,关联得到查询对象数据,是一种文本属性转链接的方式
配置 |
说明 |
---|---|
查询对象 |
选择关联查询的对象,可查询所有对象 |
关联条件 |
选择当前对象的非计算文本属性,用于与查询对象的业务主键进行匹配 |
过滤条件 |
新建计算链接后,可在链接属性栏中设置过滤条件,过滤条件对查询对象进行过滤 |
QL模式:通过DeepQL语句定义表达式,用于按条件取值、使用全局变量查询对象数据等复杂计算逻辑
保存计算属性/链接时,会推断类型与基数。支持以下属性类型与基数、链接对象与基数,可在QL模式的查询语句中直接输入固定值
分类 |
属性类型/链接对象 |
基数 |
固定值示例 |
---|---|---|---|
计算属性 |
文本 |
单选 |
‘文本’ |
计算属性 |
多语言文本 |
单选 |
仅UI模式的引用属性为多语言文本属性时,可推断出该类型 |
计算属性 |
布尔值 |
单选 |
true、false |
计算属性 |
整数 |
单选 |
12345 |
计算属性 |
小数 |
单选 |
<decimal>123.45 |
计算属性 |
日期时间 |
单选 |
<cal::local_datetime>’2025-02-15 12:30:00’、<cal::local_datetime>’2025-02-15T12:30:00’ |
计算属性 |
枚举值 |
单选 |
仅UI模式的引用属性为枚举值属性时,可推断出该类型 |
计算属性 |
文件 |
单选 |
仅UI模式的引用属性为文件属性时,可推断出该类型 |
计算链接 |
所有链接对象 |
单选、多选 |
输入对象数据,可通过 |
新建链接为正向链接,每个正向链接都有一个虚拟的反向链接。需要注意,计算链接的反向链接无效,由于计算链接本身是计算出来的
假设对象B1有一个指向对象B2的正向链接.link
,那么对象B2有一个指向对象B1的反向链接.<link[is B1]
<
是反向链接标识
[is ${目标对象编码}]
表示反向链接的目标对象,由于可能存在多个对象有相同编码的正向链接指向同一个目标对象
以需求对象Requirement、任务对象Task为例,任务对象有一个指向需求对象的链接requirement。需求对象新建计算链接related_task(关联任务),查询链接requirement的反向链接.<requirement[is Task]
基于正向链接,计算反向链接值
可通过链接(含正/反向链接)级联查询到其他对象的属性/链接,无需进行额外关联。级联查询由链接路径、查询属性/链接组成
以需求对象Requirement、人员对象Person为例,任务对象有一个指向用户对象SystemUser的链接req_owner(需求负责人);人员对象是用户对象的信息扩展表,有一个指向用户对象的链接system_user(系统用户),与一个指向部门对象Department的链接department(部门)。需求对象新建计算链接department,获取需求负责人的所属部门
先通过链接req_owner联查到用户对象
再通过反向链接.<system_user[is Person]
联查到人员对象
最后查询链接department,即.req_owner.<system_user[is Person].department
。其中,.req_owner.<system_user[is Person]
是链接路径,.department
是查询链接
如上所述,计算属性UI模式、计算链接级联模式的过滤条件仅支持过滤引用属性/链接的最后一层对象
对查询属性的所属对象进行过滤,即(select .link1.link2.linkN filter ...).查询属性
对查询链接的目标对象进行过滤,即select .link1.link2.linkN.查询链接 filter ...
如需过滤链接路径中其他层对象,则使用QL模式。假设对链接link2的目标对象进行过滤,即(select .link1.link2 filter ...).linkN.查询属性/链接
以需求对象Requirement、任务对象Task为例,任务对象有一个指向需求对象的链接requirement。需求对象新建计算属性,统计每个需求的关联任务数据
新建计算属性task_count,统计每个需求的关联任务总数
新建计算属性min_p_start_date,统计每个需求关联任务的最早计划开始时间
新建计算属性max_p_end_date,统计每个需求关联任务的最晚计划结束时间
新建计算属性e_man_day_sum,统计每个需求关联任务的预估人天之和
新建计算属性dev_e_man_day_sum,统计每个需求关联开发任务的预估人天之和
新建计算属性dev_e_man_day_ratio,统计每个需求关联开发任务的预估人天占比。DeepQL语法中的加减乘除同常用计算,即数字间的+、-、*、/。可通过if…else表达式兼容除法中分母为0的问题
编辑方式 |
查询语句 |
---|---|
QL模式 |
0 if .e_man_day_sum = 0 else .dev_e_man_day_sum / .e_man_day_sum |
通常使用计算链接的联查模式实现文本属性转链接,建议尽量直接新建非计算链接记录值
日志对象Log中的文本属性operate_user_id记录操作用户ID。可新建计算链接operator,根据操作用户ID,查询用户对象SystemUser获取操作用户
需求对象Requirement中的文本属性cur_process_id记录当前流程实例ID。可新建计算链接cur_process,根据当前流程实例ID,查询流程实例对象DFProcess获取当前流程实例
如果计算链接的联查模式不能满足计算逻辑,则使用QL模式
以上述日志对象Log为例,计算链接operator的联查模式配置对应QL模式查询语句select spacezauoyn::SystemUser filter .user_id = Log.operate_user_id
,可基于此进行修改。DeepQL语句中可省略当前应用模块,直接查询对象
需要注意,如果查询对象为当前对象,对象前需加上detached,即select detached ${对象编码} filter ...
。由于每条对象数据查询当前对象时,数据范围仅当前数据,加上detached表示数据范围为整个对象数据
还有一种简单方式,即通过QL模式查询语句<${对象编码}>.${属性编码}
强转属性值(表示业务主键)为对象数据,例如:<spacezauoyn::SystemUser>.operate_user_id。查询数据时,如果查询对象不包含某个属性值即业务主键,查询失败并报错,类似:’spacezauoyn::SystemUser’ with user_id ‘1’ does not exist
以下介绍常用计算的表达式,DeepQL语法详见:DeepQL查询语句
通过??
进行空值兼容,语法如:A ?? B
,表示A非空则为A,否则为B。例如:需求对象Requirement上述计算属性min_p_start_date,调整为如果关联任务的最早计划开始时间为空,则取需求的迭代开始时间。由于空值会影响四则运算、条件判断等,导致结果为空,可使用该表达式进行兼容。例如:.property1 + .property2
调整为(.property1 ?? 0) + (.property2 ?? 0)
;(条件)
即布尔值表达式调整为((条件) ?? false)
编辑方式 |
查询语句 |
---|---|
QL模式 |
min(.<requirement[is Task].p_start_date) ?? .iteration.start_date |
通过if…else表达式实现按条件取值,语法如:左表达式 if 条件 else 右表达式
,表示条件为true则取左表达式的值,条件为false则取右表达式的值。例如:需求对象Requirement新建计算属性overall_task_status,统计每个需求关联任务的整体状态
编辑方式 |
查询语句 |
---|---|
QL模式 |
‘未开始’ if count(.<requirement[is Task]) = 0 else |
通过json键值对实现值映射。例如:任务对象Task新建计算属性task_progress,按任务状态映射至表示进度的数值,用于UX滑动条展示
编辑方式 |
查询语句 |
---|---|
QL模式 |
<decimal>json_get(to_json(‘{“not_started”:0, “in_progress”:0.5, “completed”:1}’), .task_status) ?? 0 |
通过基于自我链接的递归函数,统计指定成员的末级成员集合:cal::base、cal::ibase(含指定成员),后代成员集合:cal::descendant、cal::idescendant(含指定成员),祖先成员集合:cal::ancestor、cal::iancestor(含指定成员)。例如:部门对象Department新建计算属性idsc_count、idsc_person_count,分别统计每个部门及后代部门的总数与人员总数。递归函数不指定自我链接时,默认按层级链接parent的层级计算;递归函数需要指定一个成员,这里不用指定如上所述,每条对象数据查询当前对象时,数据范围仅当前数据
属性/链接编码 |
编辑方式 |
查询语句 |
---|---|---|
idsc_count |
QL模式 |
count(cal::idescendant((select Department))) |
idsc_person_count |
QL模式 |
count(cal::idescendant((select Department)).<department[is Person]) |
通过++
拼接文本。例如:部门对象Department新建计算属性description,拼接部门名称与上述部门及后代部门总数,用于对象业务描述
编辑方式 |
查询语句 |
---|---|
QL模式 |
<str>json_get(.name, ‘zh-cn’) ++ ‘(’ ++ <str>.idescendant_count ++ ‘)’ |
日期时间相关表达式,包括:当前时间、日期加减、日期比较等。例如:任务对象Task新建计算属性is_delayed,如果当前时间超过计划结束时间加7天,但任务状态非已完成,则认为任务延期
编辑方式 |
查询语句 |
---|---|
QL模式 |
(.task_status ?? ‘not_started’) != ‘completed’ and (.p_end_date + <cal::relative_duration>’7 days’) < cal::local_datetime_of_statement() |
使用全局变量的表达式,详见:全局变量。例如:人员对象Person新建计算属性is_myself,表示是否当前用户数据
编辑方式 |
查询语句 |
---|---|
QL模式 |
.system_user = global spacezauoyn::current_user |
回到顶部
咨询热线