Escludere i risultati dalla query DBpedia SPARQL basata sul prefisso URI

Come posso escludere un gruppo di concetti quando si utilizza l’ endpoint DBpedia SPARQL ? Sto usando la seguente query di base per ottenere un elenco di concetti:

SELECT DISTINCT ?concept WHERE { ?xa ?concept } LIMIT 100 

Risultati SPARQL

Questo mi dà una lista di 100 concetti. Voglio escludere tutti i concetti che rientrano nella class / gruppo YAGO (cioè, i cui IRI iniziano con http://dbpedia.org/class/yago/ ). Posso filtrare singoli concetti come questo:

 SELECT DISTINCT ?concept WHERE { ?xa ?concept FILTER (?concept != ) } LIMIT 100 

Risultati SPARQL

Ma quello che non riesco a capire è come escludere tutte le sottoclassi YAGO dai miei risultati? Ho provato a usare un * come questo ma questo non ha ottenuto nulla:

 FILTER (?concept != ) 

Aggiornare:

Questa query con regex sembra fare il trucco, ma è davvero, molto lento e brutto. Non vedo davvero l’ora di un’alternativa migliore.

 SELECT DISTINCT ?type WHERE { [] a ?type FILTER( regex(str(?type), "^(?!http://dbpedia.org/class/yago/).+")) } ORDER BY ASC(?type) LIMIT 10 

Potrebbe sembrare un po ‘imbarazzante, ma il tuo commento sul casting su una stringa e sul fare alcuni controlli basati su stringhe è probabilmente sulla strada giusta. Puoi farlo un po ‘più efficientemente usando le funzioni di strstarts SPARQL 1.1:

 SELECT DISTINCT ?concept WHERE { ?xa ?concept FILTER ( !strstarts(str(?concept), "http://dbpedia.org/class/yago/") ) } LIMIT 100 

Risultati SPARQL

L’altra alternativa sarebbe quella di trovare una class YAGO di primo livello e di escludere quei concetti che sono rdfs:subClassOf quella class di primo livello. Probabilmente questa sarebbe una soluzione migliore a lungo termine (dal momento che non richiede il casting per le stringhe e si basa sulla struttura del grafico). Sfortunatamente, non sembra che ci sia una sola class YAGO di livello superiore paragonabile a owl:Thing . Ho appena scaricato la gerarchia di tipi YAGO dalla pagina di download di DBpedia e ho eseguito questa query, che richiede classi senza superclassi, contro di essa:

 prefix rdfs:  select distinct ?root where { [] rdfs:subClassOf ?root filter not exists { ?root rdfs:subClassOf ?superRoot } } 

e ho ottenuto questi nove risultati:

 ---------------------------------------------------------------- | root | ================================================================ |  | |  | |  | |  | |  | |  | |  | |  | |  | ---------------------------------------------------------------- 

Dato che i concetti YAGO non sono così strutturati come alcuni degli altri, sembra che l’approccio basato su stringhe potrebbe essere il migliore in questo caso. Tuttavia, se lo si desidera, è ansible eseguire una query non basata su stringhe come questa, che richiede 100 concetti, esclusi quelli che hanno uno di questi nove risultati come superclass:

 select distinct ?concept where { [] a ?concept . filter not exists { ?concept rdfs:subClassOf* ?super . values ?super { yago:YagoLegalActorGeo yago:WaterNymph109550125 yago:PhysicalEntity100001930 yago:Abstraction100002137 yago:YagoIdentifier yago:YagoLiteral yago:YagoPermanentlyLocatedEntity yago:Thing104424418 yago:Dryad109551040 } } } limit 100 

Risultati SPARQL

Non sono sicuro che finisca per essere più veloce. Il primo richiede una conversione in stringa, e gli strstarts , se implementati in modo ingenuo, devono utilizzare http://dbpedia.org/class/ in ogni concetto prima che qualcosa non corrisponda. Il secondo richiede nove confronti che, se gli IRI sono internati, sono solo controlli di id quadro degli oggetti. È una domanda interessante per ulteriori indagini.