使用MarkLogic Xquery,我有一个函数(admin:add-collection-to-publication)
,它调用另一个维护函数( admin:check-collections-exists)
来检查元素是否存在,如果它不存在则会创建该特定元素。
我调用维护功能的方式是使用 let 。这似乎是一种奇怪的方式,要做到这一点,它需要创建一个未使用的变量。我是否应该返回一个序列,调用admin:check-collections-exists
作为序列中的第一项,然后后续处理是第二个元素?只是寻找标准的优雅方式来做到这一点。我的职责是:
declare function admin:add-collection-to-publication($pub-name, $collection-name)
{
(:does this publication have a COLLECTIONS element?:)
let $unnecessary-variable := admin:check-collections-exists($pub-name)
(:now go and do what this function does:)
return "do some other stuff then return"
};
declare function admin:check-collections-exists($pub-name)
{
if(fn:exists($pubs-node/pub:PUBLICATION[pub:NAME/text()=$pub-name]/pub:COLLECTIONS))
then
"exists"
else
xdmp:node-insert-child($pubs-node/pub:PUBLICATION[pub:NAME/text()=$pub-name],<pub:COLLECTIONS/>)
};
答案 0 :(得分:1)
使用序列不可靠。 MarkLogic很可能会尝试并行评估序列项,这可能导致创建在“相同”时间或甚至在其他工作之后发生。确实最好的方法是使用let
。 let
始终在return
之前进行评估。请注意,let
也可以并行计算,但优化器足够智能,可以检测依赖关系。
就个人而言,我经常使用未使用的变量。例如,为了插入日志记录语句,在这种情况下,我有一个未使用的变量名,我每次都重用它:
let $log := xdmp:log($before)
let $result := do:something($before)
let $log := xdmp:log($result)
您还可以使用非常短的变量名称,例如$_
。或者你可以重新考虑实际给变量一个合理的名称,并使用它毕竟,即使你知道它永远不会到达其他地方
let $exists :=
if (collection-exists()) then
create()
else true()
return
if ($exists) then
"do stuff"
else () (: never reached!! :)
HTH!