Long类型元素范围索引遇字符串值报错的处理及脏数据排查
解决MarkLogic范围查询报错及找出无效文档
一、解决查询报错问题
执行cts:search(/product,cts:element-range-query(xs:QName("price"),"=",xs:long(100)))时触发类型转换错误,是因为部分文档的price值无法转为xs:long。可通过以下两种高效方式处理:
方法1:利用范围索引过滤有效文档
已创建的Long类型范围索引会自动跳过无效值,组合查询并使用索引直接返回结果,避免触发转换错误:
cts:search( /product, cts:and-query(( cts:element-range-query(xs:QName("price"), "=", xs:long(100)), cts:element-exists-query(xs:QName("price")) )), "unfiltered" )
"unfiltered"选项让查询直接调用索引结果,跳过文档级的类型验证,彻底规避无效值转换报错。
方法2:前置过滤有效文档
用fn:try()容错函数先筛选出price可正常转为xs:long的文档,再执行范围查询:
cts:search( /product[fn:try(xs:long(./price), ())], cts:element-range-query(xs:QName("price"), "=", xs:long(100)) )
fn:try()在转换失败时返回空序列,自动过滤掉含无效price的文档。
二、找出所有含无效price值的文档
定位存在price元素但值无法转为xs:long的文档,推荐两种方式:
方法1:基于范围索引高效查询
利用Long类型的取值范围(-9223372036854775808 至 9223372036854775807),通过取反查询筛选无效文档:
cts:search( /product, cts:and-query(( cts:element-exists-query(xs:QName("price")), cts:not-query(cts:element-range-query(xs:QName("price"), ">=", xs:long(-9223372036854775808))) )) )
有效price必然落在Long范围内,取反后即可得到所有无效文档,该方法完全依赖索引,性能最优。
方法2:直接过滤验证
通过fn:try()判断转换是否失败,筛选无效文档:
fn:doc()/product[fn:not(fn:exists(fn:try(xs:long(./price), ())))]
适合小批量文档排查,百万级文档优先使用方法1。
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

