2014-09-01 20 views
5

Ho una sparql-Query, che richiede determinate proprietà di URI di un determinato tipo. Come io sono sicuro, se tali proprietà esiste, io uso la parola chiave opzionale:Alternativa per parola chiave OPZIONALE in SPARQL-Queries?

PREFIX mbo: <http://creativeartefact.org/ontology/> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
SELECT * WHERE { 
    ?uri a mbo:LiveMusicEvent. 
    OPTIONAL {?uri rdfs:label ?label}. 
    OPTIONAL {?uri mbo:organisedBy ?organiser}. 
    OPTIONAL {?uri mbo:takesPlaceAt ?venue}. 
    OPTIONAL {?uri mbo:begin ?begin}. 
    OPTIONAL {?uri mbo:end ?end}. 
} 

Quando eseguo questa query contro il mio SPARQL-endpoint (Virtuoso Server), ho ottenuto l'errore:

Virtuoso 42000 Error The estimated execution time -721420288 (sec) exceeds the limit of 400 (sec).

Riducendo le clausole OPTIONAL, dopo la prima clausola rimossa il tempo di esecuzione stimato è 4106 secondi, quando rimuovo due clausole, la query viene eseguita (e restituisce immediatamente i valori).

Non riesco a vedere, perché il tempo di esecuzione stimato è salito alle stelle in questo modo con le clausole OPTIONAL aggiuntive, ma forse sto solo usando una query costruita errata?

risposta

6

I modelli OPZIONALI sono generalmente costosi da valutare (rispetto ai modelli di join "normali") per un motore SPARQL. In questo caso, l'errore indica che il pianificatore di query di Virtuoso stima che la query sia troppo complessa da eseguire entro il limite di tempo impostato (si noti che è stime, quindi il valore preciso potrebbe essere errato).

Avete diverse alternative. Molti di questi prevedono di fare più di una query, però. Un modello comune è il modello "recuperare-e-iterare" - in primo luogo fare una query che recupera tutte le istanze di mbo:LiveMusicEvent:

SELECT ?uri WHERE { ?uri a mbo:LiveMusicEvent } 

e poi si scorrere i risultati e recuperare le proprietà opzionali di ogni istanza:

SELECT * 
WHERE { VALUES(?uri) { <http://example.org/instance1> } 
     OPTIONAL {?uri rdfs:label ?label}. 
     OPTIONAL {?uri mbo:organisedBy ?organiser}. 
     OPTIONAL {?uri mbo:takesPlaceAt ?venue}. 
     OPTIONAL {?uri mbo:begin ?begin}. 
     OPTIONAL {?uri mbo:end ?end}. 
} 

Come si può vedere, utilizzo uno VALUES clause per inserire i risultati dell'ID dell'istanza dalla prima query in questa seconda query. In questo esempio, sto assumendo iterate una per una e quindi eseguo una query per ogni istanza, ma come ulteriore ottimizzazione potreste armeggiare aggiungendo più di una istanza nella clausola VALUES in un colpo solo (ovviamente non tutte in una volta tuttavia, poiché ciò renderebbe la query la stessa complessità dell'originale).

A proposito, VALUES è una funzionalità SPARQL 1.1 e non sono sicuro che Virtuoso lo supporti. In caso contrario, è possibile ottenere lo stesso effetto utilizzando una clausola FILTER o semplicemente "manualmente" sostituendo tutte le occorrenze della variabile ?uri con l'id di istanza per ciascuna iterazione.

Un altro modo per gestirlo è eseguire prima una query COSTRUTTIVA che recuperi un sottoinsieme rilevante di dati dall'origine più grande e quindi eseguire la query più complessa con gli optionals su tale sottoinsieme. Per esempio:

CONSTRUCT 
WHERE { 
    ?uri a mbo:LiveMusicEvent; 
     ?p ?o . 
} 

sarà recuperare tutti i dati relativi ai casi LiveMusicEvent come un grafo RDF. Esegui il pop-up del grafico in un modello RDF locale (ad esempio un modello di sesamo o un repository in-memory se stai lavorando in Java) e interrogalo ulteriormente da lì.

+0

Una delle cose che mi piacerebbe davvero (ma non ho molta idea di quanto costosa sarebbe) è la possibilità di fare qualcosa come 'from [construct {...} dove {...}] select ... dove {...} '. Renderebbe alcune attività difficili molto facili. –

+0

@JoshuaTaylor mi è sempre sembrato strano che "COSTRUIRE" (che, in un certo senso, è il tipo di query più "naturale" per RDF) non è facile combinare/concatenare con altre query. Abbiamo sottoselezioni - perché non i sub-costrutti?Penso che sia una di quelle funzionalità in cui il WG è appena andato "Potrebbe essere bello, ma non ora". –

+0

Sì, sarebbe bello avere in futuro, in realtà abbiamo un'implementazione delle sottocommissioni 'COSTRUISCI 'internamente a YarcData sebbene non nella clausola' FROM'. Li usiamo come un modo per invocare analisi di grafici più tradizionali (ad esempio k-means, percorso più breve, ecc.) Usandoli come sottoquery con modificatori personalizzati applicati in modo tale da poter essere annidati con cura all'interno di un normale schema grafico – RobV