Synonym from DBpedia is getting unnecessary links - sparql

The below query having 2 problem :
- Getting additional link for me in synonym, I want to just show the detail as coming in the page - http://dbpedia.org/page/Shortness_of_breath
- Showing field as a link rather than text.
SELECT ?abstract ?icd10 ?icd9 ?icd ?field ?synonyms
WHERE
{
VALUES ?name { 'Shortness of breath'#en } ?s rdfs:label ?name; dbo:abstract ?abstract
FILTER langMatches(lang(?abstract),'en')
FILTER langMatches(lang(?name),'en')
OPTIONAL {?s dbo:icd10 ?icd10 }
OPTIONAL {?s dbo:icd9 ?icd9 }
OPTIONAL {?s dbo:icd ?icd }
OPTIONAL {?s dbp:field ?field }
OPTIONAL {?s dbp:synonyms ?synonyms }
}

Related

SPARQL query to remove "#en"

I have a large skos taxonomy that has some incorrect notation properties. Most of the properties are xsd:string but some appear with a "#en" language string. I want to modify the triples so as to remove the language string from these triples and convert them to xsd:string.
I tried the query below. It doesn't report any errors and commits successfully.
DELETE { ?s ?p ?o }
INSERT { ?s ?p ?o2 }
WHERE
{
?s skos:notation ?o .
BIND(STRDT(STR(?o), xsd:string) AS ?o2)
}
However, the query does not result in any change to the triples data. Can anyone suggest where I might be going wrong?
Variable ?p in your query appears to be unbound. Try:
DELETE { ?s skos:notation ?o }
INSERT { ?s skos:notation ?o2 }
WHERE
{
?s skos:notation ?o .
BIND(STRDT(STR(?o), xsd:string) AS ?o2)
}

Return values under same column in SPARQL query

Given three possible objects for triples, foaf:name, foaf:givenName, and foaf:familyName, where statements either have foaf:name or foaf:givenName + foaf:familyName, e.g.:
<uri1> <foaf:name> "Lolly Loozles" .
<uri2> <foaf:givenName> "Stotly" .
<uri2> <foaf:familyName> "Styles" .
wondering how to write a SPARQL query to return a new variable like pretty_name that is either the value of foaf:name or a concatenation of the values from foaf:givenName and foaf:familyName.
Resulting in something like:
?o | ?pretty_name
----------------------
<uri1> | Lolly Loozles
<uri2> | Stotly Styles
This is what I have so far, but unsure how to proceed:
PREFIX : <https://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
# select two variables, not ideal...
SELECT ?foaf_fullName ?pretty_name
WHERE {
# Find all triples
?s ?p ?o .
# Binds
OPTIONAL { ?s foaf:name ?foaf_fullName }
OPTIONAL { ?s foaf:givenName ?givenName }
OPTIONAL { ?s foaf:familyName ?familyName }
# Filter where predicate is part of list
FILTER (?p IN (foaf:name, foaf:givenName, foaf:familyName ) )
# Binds
BIND( CONCAT(?givenName, ' ', ?familyName) AS ?pretty_name ) .
}
I had imagined, and tried, adding another BIND to add to ?pretty_name, but the SPARQL engine wouldn't have it:
BIND( ?foaf_fullName AS ?pretty_name ) .
I also had luck writing a CONSTRUCT statement to get the values I'm looking for, but don't have the ability to write back to this triplestore (for a number of reasons):
CONSTRUCT {
?s :hasPrettyName ?foaf_fullName .
?s :hasPrettyName ?pretty_name .
}
I had thought that CONSTRUCT could accompany SELECT, but must have been mistaken?
Any insight or suggestions would much appreciated.
Using #StanislavKralin comment/suggestion to use COALESCE without IF clauses works great:
PREFIX : <https://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
# select two variables, not ideal...
SELECT ?foaf_fullName ?pretty_name
WHERE {
# Find all triples
?s ?p ?o .
# Binds
OPTIONAL { ?s foaf:name ?foaf_fullName }
OPTIONAL { ?s foaf:givenName ?givenName }
OPTIONAL { ?s foaf:familyName ?familyName }
# Filter where predicate is part of list
FILTER (?p IN (foaf:name, foaf:givenName, foaf:familyName ) )
# Binds
BIND( COALESCE(?foaf_fullName, CONCAT(?givenName, ' ', ?familyName)) AS ?pretty_name )
}

Aggregate properties

I'm developing my own Fuseki endpoint from some DBpedia data.
I'm in doubt on how to aggregate properties related to a single resource.
SELECT ?name ?website ?abstract ?genre ?image
WHERE{
VALUES ?s {<http://dbpedia.org/resource/Attack_Attack!>}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image } .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}
SPARQL endpoint: http://dbpedia.org/sparql/
This query returns 2 matching results. They are different just for the dbo:genre value. There is a way I can query the knowledge base and retrieving a single result with a list of genres?
#chrisis's query works well on the DBpedia SPARQL Endpoint, which is based on Virtuoso.
However, if you are using Jena Fuseki, you should use more conformant syntax:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT
?name
(SAMPLE(?website) AS ?sample_website)
(SAMPLE(?abstract) AS ?sample_abstract)
(SAMPLE(?image) AS ?sample_image)
(GROUP_CONCAT(?genre; separator=', ') AS ?genres)
WHERE {
VALUES (?s) {(<http://dbpedia.org/resource/Attack_Attack!>)}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
} GROUP BY ?name
The differences from the #chrisis's query are:
Since GROUP_CONCAT is an aggregation function, it might be used with GROUP BY only;
Since GROUP BY is used, all non-grouping variables should be aggregated (e.g. via SAMPLE);
GROUP_CONCAT syntax is slightly different.
In Fuseki, these AS in the projection are in fact superfluous: see this question and comments.
Yes, the GROUP_CONCAT() function is what you want.
SELECT ?name ?website ?abstract (GROUP_CONCAT(?genre,',') AS ?genres) ?image
WHERE{
<http://dbpedia.org/resource/Attack_Attack!> a dbo:Band ;
foaf:name ?name;
dbo:abstract ?abstract .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:genre ?genre } .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbp:website ?website} .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}

DBpedia SPARQL filter does not apply to all results

A FILTER NOT EXISTS allows some results through when combined with OPTIONAL triples.
My query:
SELECT DISTINCT * WHERE
{
{
?en rdfs:label "N'Djamena"#en .
BIND("N'Djamena" AS ?name) .
}
UNION {
?en rdfs:label "Port Vila"#en .
BIND("Port Vila" AS ?name) .
}
UNION {
?en rdfs:label "Atafu"#en .
BIND("Atafu" AS ?name) .
}
FILTER NOT EXISTS { ?en rdf:type skos:Concept } .
OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") . }
OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") . }
}
LIMIT 100
This query gets the three places as expected, but it also pulls back "Category:Atafu", which should be filtered out by virtue of having "rdf:type skos:Concept".
When used without the OPTIONAL lines, I get the three places expected. When used with those clauses non-optionally, I get only two of the countries, because Atafu doesn't have a page in Portuguese.
I can also move the FILTER NOT EXISTS statement into each of the UNION'd country blocks, but that seems to hurt the server's response time.
Why does the FILTER NOT EXISTS clause filter out "Category:N'Djamena" and Category:Port_Vila but not "Category:Atafu" when followed by OPTIONAL?
I really have no idea why your query doesn't work. I'd have to chalk it up to some weird Virtuoso thing. There's definitely something strange going on. For instance, if you remove the bind for the last name, you'll get the resources you're expecting:
SELECT DISTINCT * WHERE
{
{
?en rdfs:label "N'Djamena"#en .
BIND("N'Djamena" AS ?name) .
}
UNION {
?en rdfs:label "Port Vila"#en .
BIND("Port Vila" AS ?name) .
}
UNION {
?en rdfs:label "Atafu"#en .
}
FILTER NOT EXISTS { ?en rdf:type skos:Concept }
OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") }
OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") . }
}
LIMIT 100
SPARQL results
It's really pretty weird. Here's a modified version of your query that gets the results you're looking for. It uses values instead of union, which makes the query simpler. It should be logically equivalent, though, so I'm not sure why it makes a difference.
select distinct * where {
values ?label { "N'Djamena"#en "Port Vila"#en "Atafu"#en }
?en rdfs:label ?label .
optional { ?en owl:sameAs ?pt . filter regex(?pt, "pt.dbpedia") }
optional { ?en owl:sameAs ?es . filter regex(?es, "es.dbpedia") }
filter not exists { ?en a skos:Concept }
bind(str(?label) as ?name)
}
SPARQL results
I'd actually clean up the string matching though, since regular expressions are probably more power than you need here. You just want to check whether the value starts with a given substring:
select ?en ?label (str(?label) as ?name) ?es ?pt where {
values ?label { "N'Djamena"#en "Port Vila"#en "Atafu"#en }
?en rdfs:label ?label .
optional { ?en owl:sameAs ?pt . filter strstarts(str(?pt), "http://pt.dbpedia") }
optional { ?en owl:sameAs ?es . filter strstarts(str(?es), "http://es.dbpedia") }
filter not exists { ?en a skos:Concept }
}
SPARQL results

Sparql query delete all statements

I would like to delete all statements related to an object that contains certain characters in the label. I am using the query:
DELETE
{?term ?p ?o}
WHERE
{
?term rdfs:label ?label.
FILTER(regex(?label, "xx", "i"))
?term ?p ?o.
}
However, this query seems to fail to delete all the statements that contain the subject of this statement as object. Then I seem to need another query.
DELETE
{?s ?p ?term}
WHERE
{
?term rdfs:label ?label.
FILTER(regex(?label, "xx", "i"))
?s ?p ?term.
}
The SELECT * does not seem to work for DELETE, and I have also tried to model a UNION within DELETE with no success. Could you please point me to the solution? Many thanks.
try this. it worked for me both for insert and delete
DELETE
{?term ?p ?o}
WHERE
{
SELECT ?term ?p ?o
WHERE{
?term rdfs:label ?label.
FILTER(regex(?label, "xx", "i"))
}
}