2014-11-02 22 views
9

SPARQL property path le query di lunghezza arbitraria richiedono l'utilizzo di proprietà specifiche. Voglio interrogare e trovare qualsiasi percorso che inizia da una risorsa e termina in un'altra risorsa. Per esempio:query del percorso delle proprietà SPARQL con proprietà arbitrarie

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

dove ?p* specifica un percorso. C'è un modo per farlo?

+0

ho qualche dubbio sul fatto che è possibile con SPARQL (cosa sarebbe '? P' legarsi alla stringa SPARQL che costituisce il percorso delle proprietà concrete?), e si potrebbe voler vedere cosa hanno fatto le persone [RelFinder] (http://www.visualdataweb.org/relfinder.php) per scoprirlo (altro o meno) connessioni arbitrarie tra due risorse. –

+1

Puoi usare i caratteri jolly facendo qualcosa come '(<> |! <>) *', Che ti permetterebbe di scoprire * se * c'è un percorso da un luogo a un altro, ma non puoi usare le variabili nei percorsi delle proprietà . –

risposta

12

Hai ragione che non è possibile utilizzare le variabili nelle espressioni del percorso di proprietà. Ci sono alcune cose che puoi fare con che potrebbe aiutarti.

Un jolly per controllare se un percorso esiste

È possibile utilizzare un carattere jolly prendendo la disgiunzione di esso e la sua negazione, in modo da poter fare una semplice query che controlla se c'è un percorso di collegamento due risorse:

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

Se avete un prefisso : definito, che può essere ancora più breve, dal momento che è un : IRI valida:

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

Se v'è un percorso (o percorsi multipli) tra due nodi, è possibile dividere in su utilizzando percorsi jolly uniti da ?p, e così trovare tutte le ?p s che si trovano sul percorso:

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

È possibile rendere ancora più breve che, secondo me, utilizzando i nodi vuoti al posto di ?x e ?y:

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

(che potrebbe non funzionare, tu GH. Mi sembra di ricordare la grammatica che in realtà non consente di disabilitare i percorsi delle proprietà in alcuni punti all'interno di nodi vuoti. Non sono sicuro.)

Per un singolo percorso, ottenere le proprietà e le posizioni, quindi group_concat

Ora, nel caso in cui non v'è solo un percorso tra due risorse, si può anche ottenere le proprietà lungo che percorso, insieme con le loro posizioni. È possibile ordinare da tali posizioni e quindi utilizzare un gruppo per concatenare le proprietà in ordine in una singola stringa. Questo è probabilmente il più semplice da vedere con un esempio. Supponiamo che hai i seguenti dati, che ha un unico percorso :a-:d:

@prefix : <urn:ex:> . 

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

Quindi è possibile utilizzare una query come questa per ottenere ogni proprietà nel percorso e la sua posizione. (Questo funziona solo se c'è un unico percorso, però. Vedere la mia risposta a Is it possible to get the position of an element in an RDF Collection in SPARQL? per un po 'di più su come funziona.)

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 | 
------------- 

Ora, se ordinate questi risultati da ?pos e avvolgere che in un'altra, quindi è possibile utilizzare group_concat su ?p per ottenere una singola stringa delle proprietà nell'ordine. (L'ordine che viene preservato non è garantito, ma è un comportamento piuttosto comune.Vedere la mia risposta a obtain the matrix in protege per un altro esempio di come funziona questa tecnica, e my answer to Ordering in GROUP_CONCAT in SPARQL 1.1 per la discussione sul perché non è garantito.)

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

Perché preoccuparsi anche con l'URI vuoto '<>'? Le combo del motore triplestore/SPARQL consentono effettivamente questo? Fuseki sostituisce gli URI vuoti con l'URL locale al grafico corrente. Sembra che tu possa omettere l'URI vuoto e solo optare per '(! <>) *' –

+0

@Blakeregalia sì, è molto improbabile che possa causare un problema, ma a volte le persone usano l'uris in modi strani. Usare l'alternativa ottiene tutto, usando la negazione si ottiene tutto tranne uno. Se sei sicuro di non essere usato, la semplice negazione va bene. –