Вот подход, который работает, если существует не более одного пути между интересующими вас узлами. Если у вас есть такие данные (обратите внимание, что есть разные свойства, соединяющие ресурсы):
@prefix : <https://stackoverflow.com/q/3914522/1281433/>
:a :p :b .
:b :q :c .
:c :r :d .
Затем запрос, подобный следующему, находит расстояние между каждой парой узлов.Путь свойства (:|!:)
состоит из свойства, которое является либо :
, либо чем-то отличным от :
(т. Е. Чем угодно).Таким образом, (:|!:)*
- ноль или более вхождений любого свойства;это подстановочный путь.(Используемая здесь методика более подробно описана в Можно ли получить положение элемента в RDF-коллекции в SPARQL? .)
prefix : <https://stackoverflow.com/q/3914522/1281433/>
select ?begin ?end (count(?mid)-1 as ?distance) where {
?begin (:|!:)* ?mid .
?mid (:|!:)* ?end .
}
group by ?begin ?end
order by ?begin ?end ?distance
--------------------------
| begin | end | distance |
==========================
| :a | :a | 0 |
| :a | :b | 1 |
| :a | :c | 2 |
| :a | :d | 3 |
| :b | :b | 0 |
| :b | :c | 1 |
| :b | :d | 2 |
| :c | :c | 0 |
| :c | :d | 1 |
| :d | :d | 0 |
--------------------------
Просто найтиЧтобы определить, существует ли путь между двумя узлами, который меньше определенной длины, вы используете запрос ask
вместо select
, фиксируете значения ?begin
и ?end
и скорее ограничиваете значение count(?mid)-1
чем привязать его к ?distance
.Например, есть ли путь от :a
до :d
длиной менее трех?
prefix : <https://stackoverflow.com/q/3914522/1281433/>
ask {
values (?begin ?end) { (:a :d) }
?begin (:|!:)* ?mid .
?mid (:|!:)* ?end .
}
group by ?begin ?end
having ( (count(?mid)-1 < 3 ) )
Ask => No
С другой стороны, существует путь от :a
до :c
сдлина менее 5:
prefix : <https://stackoverflow.com/q/3914522/1281433/>
ask {
values (?begin ?end) { (:a :c) }
?begin (:|!:)* ?mid .
?mid (:|!:)* ?end .
}
group by ?begin ?end
having ( (count(?mid)-1 < 5 ) )
Ask => Yes