【问题标题】:Implement For Loop in Marklogic Javascript?在 Marklogic Javascript 中实现 For 循环?
【发布时间】:2018-01-17 18:37:03
【问题描述】:

我可以使用下面的 XQuery 获取集合中文档的所有 URI:

for $doc in fn:collection("transform") 
return xdmp:node-uri($doc)

但是,当我尝试在 MarkLogic 的 Javascript 模块中实现这一点时,它只获取数据库集合中的最后一个文档。

'use strict';
declareUpdate()
var docs = fn.collection("transform");
for(var doc of docs) {
  xdmp.nodeUri(doc)
}

它没有给出集合中的所有 URI,而是只返回文档的最后一个 URI。

如何让它返回所有的 URI?

【问题讨论】:

    标签: javascript marklogic sjs


    【解决方案1】:

    创建一个数组并将每个 URI 添加到您的 for 循环中的该数组中,然后返回该数组:

    'use strict';
    declareUpdate()
    var docs = fn.collection("transform");
    var results = [];
    for (var doc of docs) {
     results.push(xdmp.nodeUri(doc));
    }
    results;
    

    或者使用Sequence.from()返回一个Sequence

    'use strict';
    declareUpdate()
    var docs = fn.collection("transform");
    var results = [];
    for (var doc of docs) {
     results.push(xdmp.nodeUri(doc));
    }
    Sequence.from(results);
    

    但是,如果您只是想返回 URI,那么将 cts.uris()cts.collectionQuery() 一起使用会更好/更容易:

    'use strict';
    declareUpdate();
    cts.uris("", null, cts.collectionQuery("transform"));
    

    【讨论】:

    • @Seeker - 请使用数组文字语法创建您的数组:var results = [];此外,如果您使用 MarkLogic 9,我建议您使用 let 或 const 关键字,如下所示: const results = [].
    • @Mads Hansen - 有什么方法可以直接读取 uri 而不是推入数组,因为,如果我的收藏有数百万个 uri,那么将 uri 推入数组本身将花费很多时间,这会影响性能。我的意思是for $doc in fn:collection("transform") return xdmp:node-uri($doc),我们在不使用数组的情况下从单个函数获取值。
    • 如果您只想返回特定集合中文档的 URI,那么使用 cts.uris()cts.collectionQuery() 会更容易。我已经更新了一个例子。
    【解决方案2】:

    没有一个答案能解释为什么他们解决了起源问题,或者核心误解是什么。它们是正确的答案,但原因并不明显。

    除了对 JavaScript 如何返回计算表达式的错误假设之外,原始代码没有问题。

    从 JavaScript“脚本”返回 LAST 计算的表达式。

    这与 XQuery 不同,XQuery 将表达式累积成一个返回的序列。

    试试这个简单的案例:

    'use strict;'
    var i = 0
    i++
    i++
    i++
    

    结果:

    2
    

    不是

    [ 0 , 1 , 2 ]
    

    这并不意味着它没有'执行'“i++”3次,它意味着结果值是最后一个。

    尝试保持原始代码不变,除非在循环“做某事”中具有某种可见结果——比如 Console.log()

    'use strict';
    declareUpdate()
    var docs = fn.collection("transform");
    for(var doc of docs) {
      Console.log(xdmp.nodeUri(doc))
    }
    

    然后查看8000_ErrorLog.txt(V9)的ErrorLog.txt(V8) 您将看到每个 URI 的条目。

    这就是为什么建议将值放入数组中,因为您问“我怎样才能让它返回所有 URI?” - 你就是这样做的。

    但是“有什么方法可以直接读取 uri 而不是推入数组”的问题是完全不同的。您现有的代码目前可以做到这一点。你只是没有“看到”它,因为你没有对 URI 做任何事情,而是“把它丢在地板上”

    当您添加代码以对 URI(或节点)执行任何您想要执行的操作时,它将一个一个地执行,而无需先加载整个序列。

    试试看。

    【讨论】:

    • 感谢@Daldei 清楚地解释了为什么我们需要存储在数组中。
    猜你喜欢
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多