2009-11-19 15 views
9

In questo semplice query SPARQL ottengo una lista di soggetti il ​​cui oggetto è 42Come associare una variabile a un elemento interrogato in SPARQL

SELECT ?v WHERE { ?v ?p 42 } 

Se posso aggiungere? P come variabile

SELECT ?v ?p WHERE { ?v ?p 42 } 

Avrò due entità per riga, l'oggetto e il predicato. E se volessi tre entità, quindi includendo il 42? Qualcosa di simile:

SELECT ?v ?p ?m WHERE { ?v ?p (42 as m) } 
+1

Se 42 è davvero una costante, perché se e avanti e indietro? Quando ottieni file con due elementi, puoi semplicemente aggiungere il terzo. Oppure questo esempio è troppo semplificato e stai cercando di fare qualcosa di più complicato? –

+1

Solo curiosità. –

+0

@StefanoBorini SPARQL 1.0 ha reso questo un po 'scomodo, ma SPARQL 1.1 include 'valori' solo per questo scopo (e puoi anche specificare più di un valore costante per i dati in linea). Ho aggiunto una risposta. –

risposta

6

Standard SPARQL 1.0 in realtà non lo consente. Tuttavia, potrebbero esserci alcune estensioni specifiche per l'implementazione.

Come soluzione temporanea, se i dati contengono una tripla con 42 come oggetto letterale, è possibile farlo ad es. in questo modo:

SELECT ?v ?p ?m { ?v ?p 42, ?m FILTER(?m=42)} 

che è equivalente con

SELECT ?v ?p ?m WHERE { ?v ?p 42 . ?v ?p ?m FILTER(?m=42)} 

come è possibile scrivere i modelli di grafico che condividono lo stesso soggetto e predicato con l'elenco Object Notation virgola e la parola chiave WHERE è opzionale.

Per efficienza, si desidera utilizzare modelli di grafico di base per ridurre il triplo di lavoro a un set più piccolo e solo quindi applicare le espressioni FILTER per ottimizzare ulteriormente i risultati.

+0

Appena realizzato che questo non funziona correttamente, questo si traduce nella selezione di qualsiasi Triplo che abbia lo stesso oggetto e predicato di quelli con l'oggetto 42 in modo da ottenere potenzialmente un carico di terne miscele che sono irrilevanti alla query – RobV

+0

@RobV: True , Grazie per la segnalazione. Ho rivisto la risposta. – laalto

+0

Sì, ora funziona perfettamente ora – RobV

1
select ?v ?p ?m where { ?v ?p ?m . FILTER(?m = 42) } 
+1

Sembra ragionevole, ma a seconda del tuo motore Triple Store e SPARQL è probabile che sia molto inefficiente dato che molti motori SPARQL fanno i FILTRI in memoria, il che significa che dovresti caricare l'intero set di dati (dal ? v? p? m corrisponde a tutto) e poi deve FILTRA su tutto ciò per oggetti che sono 42 – RobV

+0

Vero, ma qualsiasi funzione SPARQL può essere inefficiente a seconda di Triple Store. Ad esempio, LIMIT e OFFSET sembrano cose sensate, queste dovrebbero funzionare velocemente, giusto? Ad esempio su AllegroGraph queste sono istruzioni di post-elaborazione, quindi molto lente se si hanno molti dati. Riguardo al filtro, FILTER, almeno su Virtuoso è molto efficiente, si traduce in una query SQL molto semplice con solo due condizioni WHERE. –

+0

Per un semplice FILTER come questo, si tradurrebbe in una semplice query SQL assumendo che il tuo negozio sia basato su SQL. LIMIT e OFFSET sono in genere post-elaborazione in qualsiasi implementazione SPARQL poiché è necessario applicare FILTER e ORDER BYs prima di poterli applicare - non mi aspetto che siano veloci su dataset di grandi dimensioni. Per un caso del genere, comunque, l'approccio di laalto è più efficiente e più portabile tra le diverse implementazioni SPARQL – RobV

0

So che questo è di andata e ritorno, ma credo che sia fattibile con una sottoquery.

Questo è un modello utile per aiutarvi a lavorare sulla query nella stretta, prima di lasciarlo sciolto su tutto il set di dati:

SELECT ?v ?p ?m WHERE { 
    { SELECT 42 as ?m WHERE { } } 
    ?v ?p ?m . 
} 
+2

In realtà, c'è una proposta da aggiungere a sparql 1.1 per farlo più direttamente. Se questo dovesse mai essere implementato, dovresti essere in grado di usare "BIND (42 AS? M)" invece della subquery. http://www.w3.org/TR/sparql11-query/#bind –

+1

In realtà, la forma ** values ​​** è ancora più bella e supporta più valori: 'values? m {42}? v? p? m '. –

5

In SPARQL 1.1, è possibile utilizzare VALUES per questo. Si può scrivere

SELECT ?v ?p ?m WHERE { 
    values ?m { 42 } 
    ?v ?p ?m 
} 
8

Un'altra variante è quello di utilizzare BIND, ad es .:

SELECT ?v ?p ?m 
WHERE { 
    BIND(42 AS ?m) 
    ?v ?p ?m 
} 

La dichiarazione BIND aggiunge semplicemente un binding per? M, che possono poi essere selezionato per il set di risultati.

+0

thumb up - funziona in python rdflib implementazione SPARQL – lowtech

1

È possibile eseguire in due modi utilizzando le associazioni parola chiave così come FILTRO

utilizzando le associazioni

SELECT ?v ?p ?m 
WHERE { ?v ?p ?m} 
BINDINGS ?m {(42)} 

utilizzando il filtro

SELECT ?v ?p ?m 
WHERE { 
?v ?p ?m 
FILTER (?m = 42) 
} 
+0

['VALUES' ha sostituito e generalizzato' BINDINGS'] (https://www.w3.org/TR/2012/WD-sparql11-query-20120724/#status) nell'ultima chiamata Working Draft di SPARQL 1.1 Query Language –

Problemi correlati