0
votes

Using MarkLogic Xquery, I have a function (admin:add-collection-to-publication) which calls another maintenance function ( admin:check-collections-exists) which checks for an element's presence and if its not present then it creates that particular element.

The way I call the maintenance function is with a let. This seems like a weird way, to do this it requires creating an unused variable. Should I instead return a sequence with the call to admin:check-collections-exists being the first item in the sequence then the subsequent processing being the second element? Just looking for the standard elegant way to do this. My functions are:

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/>)
};
1
I often use func()[0] (or func()[4000000000] if former is optimized away) to calculate something and ignore its result - BeniBela
I see xdmp:function in marklogic docs but looks like you still need a return if your function takes a parameter. xquery version "1.0-ml"; let $function := xdmp:function(xs:QName("fn:concat")) return xdmp:apply($function, "hello", " world") => hello world - Mike Whitman

1 Answers

1
votes

Using a sequence is not reliable. MarkLogic will most likely attempt to evaluate the sequence items in parallel, which could cause the creating to happen at 'same' time or even after the other work. The best approach is indeed to use a let. The let's are always evaluated before the return. Note though that let's can be evaluated in parallel as well, but the optimizer is smart enough to detect dependencies.

Personally, I often use unused variables. For example to insert logging statements, in which case I have one unused variable name that I reuse each time:

let $log := xdmp:log($before)
let $result := do:something($before)
let $log := xdmp:log($result)

You could also use a very short variable name like $_. Or you could reconsider actually giving the variable a sensible name, and use it after all, even though you know it never reaches the else

let $exists := 
    if (collection-exists()) then
        create()
    else true()
return
    if ($exists) then
        "do stuff"
    else () (: never reached!! :)

HTH!