基于AG Tamino的XQuery查询:筛选含过期item的Lorem元素
需求:查询包含过期item的Lorem元素
过期item的判定规则:
- 规则1:item的
lastDay早于指定日期 - 规则2:存在同
type且firstDay≤指定日期的替代item
受限于旧版XQuery及AG Tamino工具,已实现规则1的基础查询:
/Lorem[ipsum[dolor[item[@lastDay <= '2023-10-24']]]]
尝试过的无效实现
尝试1
/Lorem[ipsum[dolor[ item[ @firstDay <= '2023-11-25' and ( @type = *[@firstDay <= '2023-11-25']/@type or @type = *[@firstDay <= '2023-11-25']/@type ) ] ]]]
尝试2
/Lorem[ipsum[dolor[ item[ @firstDay <= '2023-11-25' and ( @type = preceding-sibling::[@firstDay <= '2023-11-25']/@type or @type = following-sibling::[@firstDay <= '2023-11-25']/@type ) ] ]]]
示例XML数据
<?xml version="1.0" encoding="UTF-8"?> <Lorem> <ipsum> <dolor> <item id="1" type="ABC" firstDay="1980-01-01" /> <item id="2" type="ABC" firstDay="1985-01-01" lastDay="1990-01-01" /> <item id="3" type="ABC" firstDay="1995-01-01" /> <item id="4" type="DEF" firstDay="2000-01-01" /> <item id="5" type="DEF" firstDay="2023-10-25" lastDay="2050-01-01" /> <item id="6" type="GHI" firstDay="2000-01-01" lastDay="2023-10-24" /> <item id="7" type="GHI" firstDay="2050-01-01" /> </dolor> </ipsum> </Lorem>
匹配/不匹配场景
匹配场景(含同type且firstDay≤指定日期的多item)
<?xml version="1.0" encoding="UTF-8"?> <Lorem> <ipsum> <dolor> <item id="1" type="ABC" firstDay="1980-01-01" /> <item id="2" type="ABC" firstDay="1985-01-01" /> <item id="4" type="DEF" firstDay="2000-01-01" /> </dolor> </ipsum> </Lorem>
不匹配场景1(无同type且firstDay≤指定日期的多item)
<?xml version="1.0" encoding="UTF-8"?> <Lorem> <ipsum> <dolor> <item id="3" type="ABC" firstDay="1995-01-01" /> <item id="4" type="DEF" firstDay="2000-01-01" /> <item id="6" type="GHI" firstDay="2000-01-01" /> </dolor> </ipsum> </Lorem>
不匹配场景2(同type的第二个item的firstDay为未来日期)
<?xml version="1.0" encoding="UTF-8"?> <Lorem> <ipsum> <dolor> <item id="3" type="ABC" firstDay="1995-01-01" /> <item id="4" type="DEF" firstDay="2000-01-01" /> <item id="6" type="DEF" firstDay="2050-01-01" /> </dolor> </ipsum> </Lorem>
当前实现的XQuery代码
for $target in input()/Lorem where $target/ipsum/dolor/item/@lastDay <= xs:date('2023-11-24') or for $type in distinct-values($target/ipsum/dolor/item/@type) where count( for $item in $target/ipsum/dolor/item where $item/@firstDay <= xs:date('2023-11-25') and $item/@type = $type return $item ) > 1 return $type return $target
高效优化方案
1. 提前过滤+减少遍历次数
先筛选出符合firstDay条件的item集合,再基于该集合做分组统计,避免原代码中对每个type重复遍历全量item:
for $target in input()/Lorem let $validItems := $target/ipsum/dolor/item[xs:date(@firstDay) <= xs:date('2023-11-25')] where -- 规则1:存在lastDay早于指定日期的item exists($target/ipsum/dolor/item[xs:date(@lastDay) <= xs:date('2023-11-24')]) or -- 规则2:存在type分组下数量>1的有效item exists( distinct-values($validItems/@type)[ count($validItems[@type = .]) > 1 ] ) return $target
优势:
- 仅遍历一次有效item集合,降低重复计算开销
- 用
exists()直接判断条件,逻辑更简洁直观
2. 利用Tamino索引优化(若支持)
如果Tamino数据库支持,可为以下字段创建索引提升性能:
- 为
item/@firstDay、item/@lastDay创建日期类型索引,避免字符串比较的性能损耗 - 为
item/@type创建值索引,加速分组匹配逻辑
3. 统一日期阈值(业务允许时)
若规则1和规则2的日期阈值可以统一,可进一步简化代码逻辑,减少日期转换和判断的次数。
内容的提问来源于stack exchange,提问作者Radboud
相关产品推荐
相关产品推荐

