Я столкнулся с той же проблемой, и ни одно из решений здесь не решило мою проблему. Вот мое решение; это было нетривиально и довольно взломать. На данный момент это работает для DBPedia и может работать для других конечных точек SPARQL, но это не гарантируется для будущих выпусков.
DBPedia использует Virtuoso, который поддерживает недокументированный аргумент для функции RAND
; Аргумент эффективно определяет диапазон, используемый для PRNG. Игра заключается в том, чтобы заставить Virtuoso поверить, что входной аргумент не может быть статически оценен перед вычислением каждой строки результата, что вынуждает программу оценивать RAND()
для каждой привязки:
select * {
?s dbo:isPartOf ?o . # Whatever your pattern is
bind(rand(1 + strlen(str(?s))*0) as ?rid)
} order by ?rid
Магия происходит в rand(1 + strlen(str(?s))*0)
, что порождает эквивалент rand()
; но заставляет его запускаться при каждом совпадении, используя тот факт, что программа не может предсказать значение выражения, которое включает некоторую переменную (в этом случае мы просто вычисляем длину IRI в виде строки). Фактическое выражение не важно, так как мы умножаем его на 0
, чтобы полностью его игнорировать, затем добавляем 1
, чтобы rand
выполнялся нормально.
Это работает только потому, что разработчики не зашли так далеко в своей статической оценке кода выражений. Они могли бы легко написать ветку для «умножить на ноль», но, увы, не сделали:)