CoRB场景下:如何快速获取MarkLogic时间栈中非Latest的最新文档
解决方案:用XQuery结合CoRB收集器一次性获取结果
可以直接编写XQuery模块作为CoRB的收集器,利用MarkLogic的内置查询和分组能力高效筛选目标文档,无需循环或多进程。
核心逻辑
- 按文档所属集合分组,对应每个时间栈家族;
- 筛选出每个组里URI与集合名称一致的主文档(即示例中的A.xml、B.xml、C.xml);
- 排除其中属于
latest集合的主文档,最终得到A.xml和C.xml。
具体XQuery收集器代码
xquery version "1.0-ml"; (: 批量获取所有URI与所属集合名一致的主文档 :) let $main-docs := cts:uris((), (), cts:and-query(( cts:collection-query(cts:collections()), cts:element-value-query(xs:QName("uri"), cts:collections()) )) ) (: 过滤掉属于latest集合的文档 :) return $main-docs[not(cts:document-in-collection(., "latest"))]
优化说明
- 用
cts:uris()的批量索引查询替代循环,大幅提升效率; - 所有筛选逻辑都在索引层面完成,避免内存中处理大量数据;
- 无需额外CoRB进程,单进程即可完成需求。
如果你的时间栈是通过URI后缀(如.1.xml)区分版本,需要找每个家族的最新版本而非主文档,可以用以下代码:
xquery version "1.0-ml"; for $coll in cts:collections() let $docs-in-coll := cts:uris((), (), cts:collection-query($coll)) (: 按URI中的版本号降序排序,取第一个为最新版本 :) let $latest-in-coll := head( sort($docs-in-coll, (), function($u) { let $parts := tokenize($u, "\.") return if (count($parts) > 2 and xs:int($parts[count($parts)-1])) then xs:int($parts[count($parts)-1]) else 0 }, "descending") ) (: 排除主文档在latest集合的家族 :) where not(cts:document-in-collection($coll, "latest")) return $latest-in-coll
CoRB配置
将上述XQuery保存为模块(如find-target-docs.xqy),在CoRB配置中指定:
COLLECTOR=find-target-docs.xqy
内容的提问来源于stack exchange,提问作者chriskelly
相关产品推荐
相关产品推荐

