删除多个文档

Delete multiple documents

以下代码有效但速度极慢。直到搜索功能一切顺利。首先,搜索函数 returns 是一个序列而不是数组(为什么?!)。其次,数组由节点组成,我需要 URI 来进行删除。第三,deleteDocument 函数采用字符串而不是 URI 数组。

执行此操作的更好方法是什么?我需要删除一年以上的文件。

这里我用xdmp.log代替document.delete只是为了安全。

var now      = new Date();
var yearBack = now.setDate(now.getDate() - 365); 

var date = new Date(yearBack);
var b    = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c    = cts.search(b, ['unfiltered']).toArray();

for (i=0; i<fn.count(c); i++) {
  xdmp.log(fn.documentUri(c[i]), "info");
};

使用 toArray 会起作用,但很可能是您的速度太慢了。 cts.search() 函数 returns 一个迭代器。因此,您所要做的就是遍历它并进行删除,直到其中没有更多项目为止。此外,您可能希望将搜索限制为 1,000 个项目。具有大量删除的事务将需要一段时间,并且可能会超时。

这里有一个遍历迭代器的例子

var now      = new Date();
var yearBack = now.setDate(now.getDate() - 365);

var date = new Date(yearBack);
var b    = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c    = cts.search(b, ['unfiltered']);

while (true) {
    var doc = c.next();

    if (doc.done == true){
        break;
    }

   xdmp.log(fn.documentUri(doc), "info");
 }

这里是一个例子,如果你想限制在前 1,000 个。

fn.subsequence(cts.search(b, ['unfiltered']), 1, 1000);

cts.uris做同样的事情:

var now      = new Date();
var yearBack = now.setDate(now.getDate() - 365);

var date = new Date(yearBack);
var b    = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c    = cts.uris("", [], b);

while (true) {
    var uri = c.next();

    if (uri.done == true){
        break;
    }

   xdmp.log(uri.value, "info");
 }

HTH!

有几点需要考虑。 1) 如果您搜索的目的是删除或任何不需要文档主体的内容,使用 returns URI 而不是节点的搜索可以更快。如果这不方便,那么让 URI 尽可能接近搜索表达式可以获得类似的结果。您希望避免让服务器只为了获取 URI 来删除文档而必须获取和展开文档。

2) 虽然在 JavaScript API 中完全涵盖了所有 MarkLogic 功能,但 JavaScript API 基于相同的基础XQuery API 使用的函数。理解这一点很有用,并查看等效的 XQuery API 文档以了解全局。例如数组与迭代器——如果 JS 搜索 API 的 returned 数组,这可能是一个巨大的性能问题,因为底层代码基于 'lazy evaluation' 序列。例如,搜索可能 return 100 万行,但如果您只查看第一行,服务器通常可以避免访问剩余的 999,999,999 个文档。同样,当您迭代时,只需要范围内引用的数据可用。如果必须将它们放入一个数组中,那么所有结果都必须预先获取并预先放入内存中。

3) 请始终牢记,return 列出事物的操作可能仅受数据库大小的限制。这就是 cts.search() 和其他函数内置于 'pagination' 的原因。您应该从一开始就为此编写代码。 通过阅读用户指南,您不仅可以更好地理解如何做某事,还可以更好地理解一旦数据库变得比内存大时如何有效地做某事——甚至根本不做。一般来说,始终为分页结果编码是个好主意——这样效率更高,而且在添加 100 个或 100 万个文档后,您的代码仍然可以正常工作。

4) 看看xdmp.nodeUrl https://docs.marklogic.com/xdmp.nodeUri, 与 fn.documentUri() 不同,此函数将在任何节点上运行,即使它不是文档节点。如果你能把它放在搜索旁边而不是删除旁边,那么系统可以优化得更好。 JavaScript 指南中的示例是一个好的开始 https://docs.marklogic.com/guide/getting-started/javascript#chapter

在你的情况下,我建议这样的事情来试验分页和提取 URI,而不必扩展文档..

var uris = []
for (var result of fn.subsequence(cts.search( ... ), 1 , 100   )
  uris.push(xdmp.nodeUri(result))

for( i in uris ) 
  xdmp.log( uris[i] )