Rajeev
Rajeev

Reputation: 123

Generate non-repeating random number using timestamp in Marklogic (XQuery)?

I want to generate non-repeating random number having time stamp in it. What could be the possible code for it?

I've tried using sem:uuid-string() function but it generates 36 long character which is very long.

Upvotes: 3

Views: 729

Answers (3)

mg_kedzie
mg_kedzie

Reputation: 437

The code below generates (with arbitrary high probability) 10 different random numbers. Every iteration of for loop inserts newly generated random number into MarkLogic database. Exception error((), 'BREAK') will be thrown when 10 different numbers were already generated.

xquery version "1.0-ml";
xdmp:document-insert("/doc/random.xml",<root><a>{xdmp:random(100)}</a></root>);
try {
for $i in (1 to 200) (:200 can be replace with larger number to reduce probability that 10 different random numbers will never be selected.:)
return    xdmp:invoke-function( function() as item()? 
{ let $myrandom:= xdmp:random(100), $last:=  count(doc("/doc/random.xml")/root/*)
return
if ($last lt 10) then (
if (doc("/doc/random.xml")/root/a/text() = $myrandom) then () else (xdmp:node-insert-after(doc("/doc/random.xml")/root/a[last()], <a>{$myrandom}</a>)))
else (if ($last eq 10) then (error((), 'BREAK')) else ())},
<options xmlns="xdmp:eval">
  <transaction-mode>update</transaction-mode>
  <transaction-mode>update-auto-commit</transaction-mode>
</options>)}
catch ($ex) {
if ($ex/error:code eq 'BREAK') then ("10 different random numbers were generated") else xdmp:rethrow() };

Upvotes: 0

DALDEI
DALDEI

Reputation: 3732

It is not possible to generate a non-repeating random number and have the results fit into finite size. If 36 bytes is too large that further limits the theoretical maximum. The server itself uses 64 bit random numbers (effectively xdmp:random) for unique ID's. Attempting to to do better, with respect to collision probability, is futile - no matter what or how long a URI you use, internally references will be created as a 64 bit random number or as a hash value. The methods recommended will not produce an effectively colliding URI with less probability then the server itself will given non-colliding URI's of any size. Most likely attempts at more complex 'random' URI generation will result in much worse results due to the subtly of pseudo random number algorithms.

Upvotes: 1

grtjn
grtjn

Reputation: 20414

I'd suggest taking a look at the ml-unique library. It provides 3 different methods for generating unique ids in MarkLogic, and explains to pros and cons of each. Maybe one of those fits your needs, or you can copy the code, and adapt as needed.

Note that a timestamp alone is not enough to guarantee uniqueness, particularly if generating multiple ids in one request, or when processing data in parallel.

The length of uuid string makes the chance of collisions very small by the way.

HTH!

Upvotes: 2

Related Questions