1

我们在数据库中有大约“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"),
                cts:not-query(cts:element-value-query(xs:QName('version'), "1"))
            ))
        )
    return 
    
            xdmp:spawn-function(function(){
            local:delete($values)
        })
4

2 回答 2

0

好吧,我认为它花费这么长时间并且可能超时的原因是您cts:value-tuples()在 for 循环中对批次进行了很多迭代,而不是将这些工作推入为每个批次调用的衍生函数中。

将分页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"),
            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)
return 
  xdmp:spawn-function(function(){
      local:delete($x)
  })
于 2021-02-20T21:59:54.493 回答
0

从 MarkLogic 数据库中删除批量内容(使用存储桶分配)始终是一个挑战。就像 Mads 建议的那样,您应该考虑使用 CoRB。使用不同的可用选项更容易调整性能。

其次,您可以考虑使用分层存储方法——例如范围分区或查询分区(只要满足许可要求),您可以将符合所需条件的文档归档到一组林中。然后,您可以使用forest-clear()为您完成工作。

于 2021-02-22T03:27:15.727 回答