Реализовать для цикла в Marklogic Javascript?

Я могу получить все URI документов в коллекции, используя ниже XQuery:

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

Но когда я попытался реализовать это в модуле Javascript в MarkLogic, он получает только последний документ в коллекции базы данных.

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

Он не дает все URI в коллекции, но возвращает только последний URI документа.

Как я могу заставить его вернуть все URI?

2 ответа

Решение

Создайте массив и добавьте каждый из 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():

'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"));

Ни один из ответов не объясняет, почему они затрагивают вопрос о происхождении или каково основное недоразумение. Это правильные ответы, но не понятно почему.

С исходным кодом проблем нет, кроме неверного предположения о том, как JavaScript возвращает вычисленные выражения.

Последнее вычисленное выражение возвращается из сценария JavaScript.

Это отличается от 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))
}

Затем посмотрите в ErrorLog.txt (V8) 8000_ErrorLog.txt (V9). Вы увидите запись для каждого URI.

Именно поэтому предложение поместить значения в массив, так как вы спросили: "Как я могу получить его, чтобы он возвращал все URI?" - вот как ты это делаешь.

Однако вопрос "Есть ли способ читать непосредственно URI, а не вставлять в массив" совершенно другой. Ваш существующий код в настоящее время делает это. Вы просто не "видите" это, потому что вы ничего не делаете с URI, а "бросаете его на пол"

Когда вы добавляете код для выполнения того, что вы хотите сделать с URI (или узлом), он будет выполняться один за другим без предварительной загрузки всей последовательности.

Попытайся.

Другие вопросы по тегам