如何解决xdmp:spawn-function() 替代
我们在数据库中有大约“2000 万”个文档,我们创建了“10000”个徽章并使用 xdmp:spawn-function() 查询这 2000 万个文档并根据某些条件执行删除操作。但是通过查询控制台运行它,查询超时..我们可以寻找任何替代选项,以便查询不会超时
xquery version "1.0-ml";
declare variable $versionToMaintain := 10;
declare variable $batchSize := 10000;
declare function local:delete($values) {
for $value in $values
let $versionToDelete := $value[3] - $versionToMaintain
return
if ($versionToDelete > 0) then
let $query := cts:and-query((
cts:collection-query('collection name 2'),cts:element-range-query(xs:QName('version'),'<=',xs:int($versionToDelete)),cts:element-value-query(xs:QName('id'),$value[2]),cts:element-range-query(xs:QName('c:created-on'),xs:dateTime(xdmp:parseDateTime('[Y0001]-[M01]-[D01]')
))
return (cts:uris((),(),$query) ! xdmp:document-delete(.))
else ()
};
let $totalDocs :=
xdmp:estimate(
cts:search(
collection("collection name 1"),cts:not-query(cts:element-value-query(xs:QName('version'),"1")),"unfiltered"
)
)
let $totalBatches := fn:ceiling($totalDocs div $batchSize)
for $x in (1 to $totalBatches)
let $values :=
cts:value-tuples(
(
cts:uri-reference(),cts:element-reference(xs:QName('id')),cts:element-reference(xs:QName('version'))
),("skip=" || ($x - 1) * $batchSize,"truncate=" || $batchSize),cts:and-query((
cts:collection-query("collection name 1"),"1"))
))
)
return
xdmp:spawn-function(function(){
local:delete($values)
})
解决方法
好吧,我认为它花费这么长时间并且可能超时的原因是您在 for 循环中执行了很多 cts:value-tuples()
迭代批次,而不是将这些工作推入生成的为每个批次调用的函数。
将分页的 cts:value-tuples()
调用移到 local:delete()
内部,并传入 $x
批处理值,而不是元组。
xquery version "1.0-ml";
declare variable $versionToMaintain := 10;
declare variable $batchSize := 10000;
declare function local:delete($x) {
let $values :=
cts:value-tuples(
(
cts:uri-reference(),cts:element-reference(xs:QName('id')),cts:element-reference(xs:QName('version'))
),("skip=" || ($x - 1) * $batchSize,"truncate=" || $batchSize),cts:and-query((
cts:collection-query("collection name 1"),cts:not-query(cts:element-value-query(xs:QName('version'),"1"))
))
)
for $value in $values
let $versionToDelete := $value[3] - $versionToMaintain
return
if ($versionToDelete > 0) then
let $query := cts:and-query((
cts:collection-query('collection name 2'),cts:element-range-query(xs:QName('version'),'<=',xs:int($versionToDelete)),cts:element-value-query(xs:QName('id'),$value[2]),cts:element-range-query(xs:QName('c:created-on'),xs:dateTime(xdmp:parseDateTime('[Y0001]-[M01]-[D01]')))
return (cts:uris((),(),$query) ! xdmp:document-delete(.))
else ()
};
let $totalDocs :=
xdmp:estimate(
cts:search(
collection("collection name 1"),"1")),"unfiltered"
)
)
let $totalBatches := fn:ceiling($totalDocs div $batchSize)
for $x in (1 to $totalBatches)
return
xdmp:spawn-function(function(){
local:delete($x)
})
,
从 MarkLogic 数据库中删除批量内容(使用存储桶分配)始终是一个挑战。就像 Mads 建议的那样,您应该考虑使用 CoRB。使用不同的选项可以更轻松地调整性能。
其次,您可以考虑使用分层存储方法 - 例如范围分区或查询分区(前提是满足许可要求),您可以在其中将符合所需条件的文档归档到一组林中。然后您可以使用 forest-clear()
为您完成这项工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。