运行CORB时出现URI外部变量未定义错误,求排查建议
问题背景
运行CORB工具时触发URI外部变量未定义错误,以下是相关配置、代码及报错信息,排查问题根源:
CORB配置参数
THREAD-COUNT=4 URIS-MODULE=get-uri.xqy PROCESS-MODULE=report.xqy PROCESS-TASK=com.marklogic.developer.corb.ExportBatchToFileTask EXPORT-FILE-NAME=report.xml PRE-BATCH-MODULE=preProces.xqy PRE-BATCH-TASK=com.marklogic.developer.corb.PreBatchUpdateFileTask
相关XQuery模块代码
get-uri.xqy
let $uris := cts:uris((), (), cts:collection-query("InvoiceHistory")) return (count($uris), $uris)
preProces.xqy
declare variable $URI as xs:string external; (: Retrieve all relevant records from the current document :) let $records := fn:doc($URI)/records (: Group records by creation_date and calculate the sum of doc_count for each group :) let $grouped-records := for $date in distinct-values($records//document/@creation_date) let $total := sum($records/document[@creation_date = $date]/@doc_count/xs:integer(.)) return <group date="{$date}" total-docs="{$total}"/> (: Serialize the grouped records as XML and store in a temporary collection :) let $temp-doc := <results>{ $grouped-records }</results> return xdmp:document-insert("/temp/preprocessed.xml", $temp-doc)
report.xqy
declare namespace fn = "http://www.w3.org/2005/xpath-functions"; declare variable $URI as xs:string external; (: Retrieve the preprocessed data :) let $preprocessed := doc("/temp/preprocessed.xml")/results (: Generate the final report :) let $final-report := <results>{ for $group in $preprocessed/group order by $group/@date return <result date="{$group/@date}" total-docs="{$group/@total-docs}"/> }</results> return $final-report
报错信息
com.marklogic.developer.corb.CorbException: Undefined external variable at URI:
at com.marklogic.developer.corb.AbstractTask.wrapProcessException(AbstractTask.java:426)
at com.marklogic.developer.corb.AbstractTask.handleRequestException(AbstractTask.java:373)
at com.marklogic.developer.corb.AbstractTask.invokeModule(AbstractTask.java:202)
at com.marklogic.developer.corb.PreBatchUpdateFileTask.call(PreBatchUpdateFileTask.java:63)
at com.marklogic.developer.corb.PreBatchUpdateFileTask.call(PreBatchUpdateFileTask.java:30)
at com.marklogic.developer.corb.Manager.runPreBatchTask(Manager.java:790)
at com.marklogic.developer.corb.Manager.populateQueue(Manager.java:857)
at com.marklogic.developer.corb.Manager.run(Manager.java:603)
at com.marklogic.developer.corb.Manager.main(Manager.java:140)
Caused by: com.marklogic.xcc.exceptions.XQueryException: XDMP-EXTVAR:
(err:XPDY0002) declare variable $URI as xs:string external; --
Undefined external variable fn:QName("","URI")
问题根源及解决办法
根源分析
PreBatchUpdateFileTask是CORB的预批量执行任务,它在URI队列生成前全局执行,不会接收单个$URI变量($URI仅用于PROCESS-MODULE处理队列中的单个文档)。preProces.xqy中错误声明了$URI外部变量,但预批量任务不会传入该变量,因此触发未定义错误。
同时report.xqy中声明的$URI也无意义,因为它仅需读取预生成的临时文档,不需要处理单个URI。
修正步骤
- 修改preProces.xqy:移除
$URI声明,直接查询所有InvoiceHistory集合的文档进行预处理:
(: Retrieve all relevant records from all InvoiceHistory documents :) let $records := cts:search(fn:doc(), cts:collection-query("InvoiceHistory"))/records (: Group records by creation_date and calculate the sum of doc_count for each group :) let $grouped-records := for $date in distinct-values($records//document/@creation_date) let $total := sum($records/document[@creation_date = $date]/@doc_count/xs:integer(.)) return <group date="{$date}" total-docs="{$total}"/> (: Serialize the grouped records as XML and store in a temporary collection :) let $temp-doc := <results>{ $grouped-records }</results> return xdmp:document-insert("/temp/preprocessed.xml", $temp-doc)
- 修改report.xqy:移除无用的
$URI声明:
declare namespace fn = "http://www.w3.org/2005/xpath-functions"; (: Retrieve the preprocessed data :) let $preprocessed := doc("/temp/preprocessed.xml")/results (: Generate the final report :) let $final-report := <results>{ for $group in $preprocessed/group order by $group/@date return <result date="{$group/@date}" total-docs="{$group/@total-docs}"/> }</results> return $final-report
- 可选优化:由于本次任务不需要逐个处理URI,可考虑简化CORB配置,比如移除
URIS-MODULE(预批量任务已完成全局处理,PROCESS-MODULE仅需输出结果),避免不必要的URI队列生成。
内容的提问来源于stack exchange,提问作者Dharmendra Kumar Singh

