繁体   English   中英

使用Marklogic(XQuery)中的时间戳生成非重复随机数?

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

我想生成带有时间戳的非重复随机数。 可能的代码是什么?

我已经尝试过使用sem:uuid-string()函数,但它会生成36个很长的字符。

我建议看一下ml-unique库。 它提供了3种不同的方法来生成MarkLogic中的唯一ID,并解释了每种方法的优缺点。 也许其中一个符合您的需求,或者您可以复制代码,并根据需要进行调整。

请注意,仅时间戳不足以保证唯一性,特别是在一个请求中生成多个ID或并行处理数据时。

顺便说一句,uuid弦的长度使碰撞的机会非常小。

HTH!

不可能生成非重复随机数并且结果适合有限大小。 如果36个字节太大,进一步限制了理论最大值。 服务器本身使用64位随机数(有效xdmp:random)作为唯一ID。 尝试在碰撞概率方面做得更好是徒劳的 - 无论您使用什么URI或多长时间,内部引用都将被创建为64位随机数或哈希值。 推荐的方法不会产生有效碰撞的URI,但概率较小,服务器本身将给出任何大小的非碰撞URI。 由于伪随机数算法的巧妙性,最有可能尝试更复杂的“随机”URI生成将导致更糟糕的结果。

下面的代码生成(具有任意高概率)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() };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM