MarkLogic XQuery如何统计集合中满足指定条件的记录总数
问题背景
需求为实现指定条件的记录计数:统计GTM2_Shipment集合内所有文档中,Ancillary Price(对应节点路径*:Shipment/*:Ancillary/*:QuotePrice)值大于1000的记录总数量。
初始编写的XQuery代码如下:
xquery version "1.0-ml"; for $x in collection("GTM2_Shipment") where ($x/*:Shipment/*:Ancillary/*:QuotePrice/text() > 1000) return (count($x))
代码运行异常现象:总耗时9007.0781ms,返回包含532个条目的序列,共输出532行,每行的值均为1,未返回预期的总计数结果532。
问题原因
代码存在两处核心问题:
- 计数逻辑位置错误
for子句会逐一遍历集合内的文档,每命中1条符合where条件的文档就会执行一次return后的逻辑。当前return中写的count($x)是对单次迭代绑定的单个文档节点做计数,单节点的计数结果永远为1,因此最终输出532个1,没有对所有匹配结果做统一聚合计数。 - 查询性能较差
写法为全集合遍历逐节点判断值,没有利用数据库索引能力,因此查询耗时超过9秒,数据量增大后耗时会进一步升高。
修正方案
基础逻辑修正(不改变查询逻辑仅修复计数错误)
把count逻辑移到循环外层,对所有匹配的结果集做统一计数即可:
xquery version "1.0-ml"; count( for $x in collection("GTM2_Shipment") where $x/*:Shipment/*:Ancillary/*:QuotePrice/text() > 1000 return $x )
也可以简化为更精简的写法:
xquery version "1.0-ml"; count(collection("GTM2_Shipment")[*:Shipment/*:Ancillary/*:QuotePrice/text() > 1000])
性能优化写法
如果是MarkLogic数据库环境,建议给QuotePrice元素配置对应数值类型的范围索引,使用索引范围查询直接匹配结果,查询耗时可以降到毫秒级:
xquery version "1.0-ml"; count( cts:search( collection("GTM2_Shipment"), cts:elementRangeQuery(xs:QName("QuotePrice"), ">", 1000) ) )
内容的提问来源于stack exchange,提问作者Rashmita Purkayastha
相关产品推荐
相关产品推荐

