Реализовать для цикла в 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 (или узлом), он будет выполняться один за другим без предварительной загрузки всей последовательности.
Попытайся.