雖然有some limitations屬性路徑可以做,根據您的具體要求,你可能能夠得到你需要的東西在這裏。考慮一下這個數據:
@prefix : <urn:ex:>.
:a :relatedTo :b .
:b :relatedTo :c .
:c :relatedTo :d .
:a :relatedTo :e .
:e :relatedTo :f .
:f :relatedTo :g .
:h :relatedTo :i .
:i :relatedTo :j .
:j :relatedTo :k .
:k :relatedTo :l .
其中有三個:relatedTo
路徑:
a --> b --> c --> d
a --> e --> f --> g
h --> i --> j --> k --> l
我知道你的情況,你有一個特定的主題,但我們可以概括一點點,並要求在每個這些路徑的每個邊緣與這樣的查詢:
prefix : <urn:ex:>
select * where {
# start a path
?begin :relatedTo* ?midI .
FILTER NOT EXISTS { [] :relatedTo ?begin }
# grab next edge
?midI :relatedTo ?midJ .
# get to the end of the path.
?midJ :relatedTo* ?end .
FILTER NOT EXISTS { ?end :relatedTo [] }
}
order by ?start ?end
$ arq --data data.n3 --query query.sparql
-----------------------------
| begin | midI | midJ | end |
=============================
| :a | :a | :b | :d |
| :a | :b | :c | :d |
| :a | :c | :d | :d |
| :a | :a | :e | :g |
| :a | :e | :f | :g |
| :a | :f | :g | :g |
| :h | :h | :i | :l |
| :h | :i | :j | :l |
| :h | :j | :k | :l |
| :h | :k | :l | :l |
-----------------------------
它顯示每個:relatedTo
路徑的每個邊緣。你可以使輸出有點漂亮,太:
prefix : <urn:ex:>
select (concat(str(?begin),"--",str(?end)) as ?path) ?midI ?midJ where {
# start a path
?begin :relatedTo* ?midI .
FILTER NOT EXISTS { [] :relatedTo ?begin }
# grab next edge
?midI :relatedTo ?midJ .
# get to the end of the path.
?midJ :relatedTo* ?end .
FILTER NOT EXISTS { ?end :relatedTo [] }
}
order by ?path
$ arq --data data.n3 --query query.sparql
--------------------------------------
| path | midI | midJ |
======================================
| "urn:ex:a--urn:ex:d" | :a | :b |
| "urn:ex:a--urn:ex:d" | :b | :c |
| "urn:ex:a--urn:ex:d" | :c | :d |
| "urn:ex:a--urn:ex:g" | :a | :e |
| "urn:ex:a--urn:ex:g" | :e | :f |
| "urn:ex:a--urn:ex:g" | :f | :g |
| "urn:ex:h--urn:ex:l" | :h | :i |
| "urn:ex:h--urn:ex:l" | :i | :j |
| "urn:ex:h--urn:ex:l" | :j | :k |
| "urn:ex:h--urn:ex:l" | :k | :l |
--------------------------------------
同樣的方法將讓你做一些有趣的事情就像找到了相隔較遠某些節點如何:
prefix : <urn:ex:>
select ?begin ?end (count(*) as ?length) where {
# start a path
?begin :relatedTo* ?midI .
FILTER NOT EXISTS { [] :relatedTo ?begin }
# grab next edge
?midI :relatedTo ?midJ .
# get to the end of the path.
?midJ :relatedTo* ?end .
FILTER NOT EXISTS { ?end :relatedTo [] }
}
group by ?begin ?end
------------------------
| begin | end | length |
========================
| :a | :g | 3 |
| :a | :d | 3 |
| :h | :l | 4 |
------------------------
在上面提供的數據中,路徑碰巧按字母順序排列,因此排序會按正確的順序生成邊。但是,即使邊緣節點不是按字母順序排列,我們仍然可以通過計算它們在列表中的位置來按順序打印它們。這個查詢:
prefix : <urn:ex:>
select ?begin ?midI ?midJ (count(?counter) as ?position) ?end where {
?begin :relatedTo* ?counter .
?counter :relatedTo* ?midI .
FILTER NOT EXISTS { [] :relatedTo ?begin }
?midI :relatedTo ?midJ .
?midJ :relatedTo* ?end .
FILTER NOT EXISTS { ?end :relatedTo [] }
}
group by ?begin ?end ?midI ?midJ
----------------------------------
| begin | midI | midJ | .1 | end |
==================================
| :a | :a | :b | 1 | :d |
| :a | :b | :c | 2 | :d |
| :a | :c | :d | 3 | :d |
| :a | :a | :e | 1 | :g |
| :a | :e | :f | 2 | :g |
| :a | :f | :g | 3 | :g |
| :h | :h | :i | 1 | :l |
| :h | :i | :j | 2 | :l |
| :h | :j | :k | 3 | :l |
| :h | :k | :l | 4 | :l |
----------------------------------
我們沒有必要需要看到表示,計數,但你可以,而不是選擇的位置,你可以用它作爲排序條件:
prefix : <urn:ex:>
select ?begin ?midI ?midJ ?end
where {
?begin :relatedTo* ?counter .
?counter :relatedTo* ?midI .
FILTER NOT EXISTS { [] :relatedTo ?begin }
?midI :relatedTo ?midJ .
?midJ :relatedTo* ?end .
FILTER NOT EXISTS { ?end :relatedTo [] }
}
group by ?begin ?end ?midI ?midJ
order by ?begin ?end count(?counter)
並保證讓你的邊緣順序。
剛剛看到通知,對不起!除了下面的評論,我沒有取得任何進展。該項目目前暫停,但我希望很快回來! – bdkauff