2015-06-23 131 views
2

以下代码正在运行,但速度非常慢。直到搜索功能一切正常。首先,搜索函数返回一个序列而不是数组(为什么?!)。其次,数组由节点组成,我需要用于删除的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"); 
}; 

回答

5

做同样与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!

3

使用toArray会工作,但很可能是你的缓慢。 cts.search()函数返回一个迭代器。所以你所要做的就是循环播放它,并删除它,直到没有更多项目。此外,您可能希望将搜索范围限制为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"); 
} 

的例子这里是,如果你想限制到第一1000的例子。

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

感谢。函数fn.documentUri现在不适用于循环中的'doc'。 typeof显示它是一个Object。 – Thijs

+0

我认为你需要用next()。value替换next()。 MarkLogic总是返回ValueIterator类型的迭代器。 – grtjn

+0

值得考虑使用cts.uris .. – grtjn

1

有几件事要考虑。 1)如果您正在搜索删除的目的或任何不需要文档正文的内容,则使用返回URI而不是节点的搜索可以更快。如果这样做不方便,那么将URI接近搜索表达式可以获得类似的结果。您希望避免服务器不得不获取并扩展文档,以便获取URI以将其删除。

2)尽管JavaScript API对所有MarkLogic功能都有全面的覆盖,但JavaScript API基于XQuery API使用的相同底层功能。它对理解这一点很有用,并且查看等效的XQuery API文档以获取全局图。例如Arrays vs Iterators - 如果JS搜索API的返回数组可能是一个巨大的性能问题,因为底层代码是基于序列的“懒惰评估”。例如,搜索可能会返回100万行,但如果您只查看第一行,服务器通常可以避免访问剩余的999,999,999个文档。同样,当你迭代只有在范围内引用的数据需要可用。如果必须将它们放入数组中,则所有结果都必须预先提取并放入内存中。 3)请务必记住,返回事物列表的操作可能只会受限于数据库的大小。这就是为什么cts.search()和其他函数已经建立在“分页”中的原因。您应该从头开始编写代码。 通过阅读用户指南,您不仅可以更好地理解如何做某些事情,而且可以更好地理解一旦数据库变得比内存更大时,如何有效地完成这项工作,甚至完全可以做到这一点。总的来说,它总是对分页结果进行编码的好主意 - 它会更加高效,并且在添加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])