我想生成包含时间戳的非重复随机数。可能的代码是什么?
我尝试使用 sem:uuid-string()函数,但它会生成36个长字符,这个字符非常长。
答案 0 :(得分:2)
我建议您查看ml-unique库。它提供了3种不同的方法来生成MarkLogic中的唯一ID,并解释了每种方法的优缺点。也许其中一个符合您的需求,或者您可以复制代码,并根据需要进行调整。
请注意,仅时间戳不足以保证唯一性,尤其是在一个请求中生成多个ID或并行处理数据时。
顺便说一句,uuid弦的长度使碰撞的机会非常小。
HTH!
答案 1 :(得分:1)
不可能生成非重复随机数并且结果适合有限大小。如果36个字节太大,进一步限制了理论最大值。服务器本身使用64位随机数(实际上是xdmp:random)来表示唯一ID。尝试在碰撞概率方面做得更好是徒劳的 - 无论您使用什么URI或多长时间,内部引用都将被创建为64位随机数或哈希值。推荐的方法不会以较小的概率产生有效冲突的URI,因此服务器本身将给出任何大小的非冲突URI。最有可能尝试更复杂的随机'由于伪随机数算法的巧妙性,URI生成将导致更糟糕的结果。
答案 2 :(得分:0)
下面的代码生成(具有任意高概率)10个不同的随机数。 for循环的每次迭代都会将新生成的随机数插入MarkLogic数据库。当已生成10个不同的数字时,将抛出异常错误((),' BREAK')。
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() };