XQuery ベースの XML データベース内に多数のレコードがあるとします。
<widgets>
<widget id="1" name="Foo Widget" price="19.99" />
<widget id="2" name="Bar Widget" price="29.99" />
<widget id="3" name="Baz Widget" price="39.99" />
<!-- etc. -->
</widget>
「多数」とは、100 万以上を意味します。
XQuery を使用して、リストから 1 つの項目をランダムに取得したいとします。
let $widgets := for $widget in //widgets/widget
order by util:random()
return $widget
for $val in subsequence($widgets, 1, 1)
return $val
レコードの数が増えると、データベースからすべてをロードしてメモリ内で並べ替えるように見えるため、評価の実行に膨大な時間がかかります。それはO(n log 2n)かもしれないと思います。ため息が出るほどの遅さ。
これを行うための怠惰でより良い方法はありますか?
「アイテムの数を数えてから、ゼロからカウントまでの数をランダムに選択する」方法がありますが、これは避けたいと思います。
理想的には、次のような機能があれば、データベースがそれを実行できます。
let $widgets := for $widget in //widgets/widget
order by util:random()
limit 1
return $widget
これはFLOLWRでしょうね。しかし、SQL (または実際には SPARQL やその他の多くのクエリ言語) では十分に一般的なことですが、XQuery 仕様には含まれていません。
これを取得する方法はありますか?where 句を追加すればそれは可能ですが、where 句は order 句の前に評価されるため、あまり役に立ちません。
助言がありますか?(XQuery を送信するアプリケーションは Java で作成されており、XML データベースは eXist です。それが少しばかりのカーブボール的で突飛なアイデアに役立つ場合)。