2014-11-02 35 views
9

SPARQL property path Zapytania o dowolnej długości wymagają użycia określonych właściwości. Chcę zapytać i znaleźć dowolną ścieżkę, zaczynając od zasobu i kończąc na innym zasobie. Na przykład:Zapytania o ścieżki właściwości SPARQL z dowolnymi właściwościami

SELECT ?p 
WHERE { :startNode ?p* :endNode } 

gdzie ?p* określa ścieżkę. Czy jest sposób na zrobienie tego?

+0

jakoś wątpliwości, że jest to możliwe z SPARQL (co by '? P' powiązać z? ciągiem SPARQL, który tworzy konkretną ścieżkę właściwości?), a możesz chcieć sprawdzić, co zrobili ludzie [RelFinder] (http://www.visualdataweb.org/relfinder.php), aby dowiedzieć się więcej lub mniej) arbitralne połączenia między dwoma zasobami. –

+1

Możesz używać symboli wieloznacznych, wykonując coś takiego jak '(<> |! <>) *', Które pozwala ci dowiedzieć się, * czy * istnieje ścieżka z jednego miejsca do drugiego, ale nie możesz używać zmiennych w ścieżkach właściwości . –

Odpowiedz

12

Masz rację, że nie możesz używać zmiennych w wyrażeniach ścieżki właściwości. Jest jednak kilka rzeczy, które możesz zrobić, ale mogą ci pomóc.

Znak wieloznaczny, by sprawdzić czy ścieżka istnieje

Można użyć symbolu wieloznacznego biorąc alternatywą nim i jego negacji, więc można zrobić prostą kwerendę, która sprawdza czy istnieje ścieżka łącząca dwa zasoby:

<source> (<>|!<>)* <target> 

Jeśli masz : prefiks określone, że może być jeszcze krótszy, ponieważ : jest prawidłowy IRI:

<source> (:|!:)* <target> 

Jeśli istnieje ścieżka (lub wielu ścieżek) między dwoma węzłami, można podzielić go za pomocą wieloznacznych ścieżki połączone przez ?p, a więc znaleźć wszystkie ?p s, które są na ścieżce:

<source> (:|!:)* ?x . 
?x ?p ?y . 
?y (:|!:)* <target> . 

można zrobić to nawet krócej, myślę, używając puste węzły zamiast ?x i ?y:

<source> (:|!:)* [ ?p [ (:|!:)* <target> ] ] 

(to może nie działać, ty gh. Wydaje mi się, że gramatyka w rzeczywistości blokuje ścieżki własności w niektórych miejscach w pustych węzłach. Nie jestem pewien.)

Dla pojedynczej ścieżki, uzyskać właściwości i stanowisk, a następnie group_concat

Teraz, w przypadku, gdy istnieje tylko jedna ścieżka między dwoma zasobów, można nawet uzyskać właściwości wzdłuż tej ścieżkę wraz z ich pozycjami. Możesz zamówić te pozycje, a następnie użyć grupy, aby połączyć właściwości w jednym ciągu. Jest to prawdopodobnie najłatwiej zobaczyć na przykładzie. Załóżmy, że mamy następujące dane, które ma jedną ścieżkę od :a do :d:

@prefix : <urn:ex:> . 

:a :p1 :b . 
:b :p2 :c . 
:c :p3 :d . 

Następnie można użyć kwerendy w ten sposób, aby uzyskać każdą właściwość w ścieżce i jej położenia. (To działa tylko wtedy, gdy istnieje jedna ścieżka, choć. Zobacz moją odpowiedź na Is it possible to get the position of an element in an RDF Collection in SPARQL? na trochę więcej o tym, jak to działa.)

prefix : <urn:ex:> 

select ?p (count(?mid) as ?pos) where { 
    :a (:|!:)* ?mid . 
    ?mid (:|!:)* ?x . 
    ?x ?p ?y. 
    ?y (:|!:)* :d 
} 
group by ?x ?p ?y 
------------- 
| p | pos | 
============= 
| :p2 | 2 | 
| :p1 | 1 | 
| :p3 | 3 | 
------------- 

Teraz, jeśli zamówienie tych wyników przez ?pos i owinąć że zapytanie w innym, następnie można użyć group_concat na ?p, aby uzyskać pojedynczy ciąg właściwości w kolejności. (Zachowanie zamówienia nie jest gwarantowane, ale jest dość powszechnym zachowaniem.Zobacz moją odpowiedź na obtain the matrix in protege na kolejny przykład tego, jak działa ta technika i my answer to Ordering in GROUP_CONCAT in SPARQL 1.1 do dyskusji o tym, dlaczego to nie jest gwarantowane.)

prefix : <urn:ex:> 

select (group_concat(concat('<',str(?p),'>');separator=' ') as ?path) { 
    select ?p (count(?mid) as ?pos) where { 
    :a (:|!:)* ?mid . 
    ?mid (:|!:)* ?x . 
    ?x ?p ?y. 
    ?y (:|!:)* :d 
    } 
    group by ?x ?p ?y 
    order by ?pos 
} 
----------------------------------------- 
| path         | 
========================================= 
| "<urn:ex:p1> <urn:ex:p2> <urn:ex:p3>" | 
----------------------------------------- 
+0

Dlaczego nawet kłopotać się pustym identyfikatorem URI '<>'? Czy wszystkie kombinacje silników tripleystore/SPARQL rzeczywiście pozwalają na to? Fuseki zastępuje puste identyfikatory URI lokalnym adresem URL do bieżącego wykresu. Wygląda na to, że możesz pominąć pusty URI i po prostu zdecydować się na '(! <>) *' –

+0

@Blakeregalia tak, jest bardzo mało prawdopodobne, że spowoduje to problem, ale czasami ludzie używają uris w dziwny sposób. Korzystanie z alternatywy dostaje wszystko, używając negacji dostaje wszystko oprócz jednego. Jeśli jesteś pewien, że nie jest używany, to prosta negacja jest w porządku. –