Während es gibt some limitations in was Eigenschaftspfade tun können, je nach Ihren genauen Anforderungen, können Sie in der Lage zu erhalten, was Sie hier benötigen. Betrachten Sie diese Daten:
@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 .
in dem es drei :relatedTo
Pfade:
a --> b --> c --> d
a --> e --> f --> g
h --> i --> j --> k --> l
Ich weiß, dass in Ihrem Fall, Sie ein bestimmtes Thema gehabt, aber wir können ein wenig verallgemeinern, und fragen Sie nach jede Kante in jedem dieser Pfade mit einer Abfrage wie folgt:
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 |
-----------------------------
, die jede Kante von jedem :relatedTo
Pfad zeigt.Sie könnten der Ausgang ein wenig schöner, machen:
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 |
--------------------------------------
Diesen Ansatz würde Sie wie herauszufinden, einige interessante Dinge zu tun, wie weit getrennt bestimmte Knoten sind:
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 |
------------------------
In den Daten, die ich oben angegeben habe, sind die Pfade in alphabetischer Reihenfolge und die Sortierung erzeugt die Kanten in der richtigen Reihenfolge. Auch wenn die Kantenknoten nicht alphabetisch sind, können wir sie trotzdem in der Reihenfolge drucken, in der sie ihre Position in der Liste berechnen. Diese Abfrage:
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 |
----------------------------------
Wir tun nicht notwendig Notwendigkeit, sehen, die zählen, aber man konnte, anstatt die Position der Auswahl, können Sie es als Sortierbedingung verwenden:
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)
und garantiert werden, um Ihre Kanten in der Reihenfolge zu bekommen.
Ich habe nur die Benachrichtigung dafür gesehen, sorry! Ich habe keine Fortschritte gemacht, außer was in den Kommentaren unten steht. Das Projekt ist momentan in der Warteschleife, aber ich hoffe, dass ich bald darauf zurück komme! – bdkauff