SPARQL Subqueries and DELETE - sparql

I'm trying to delete a specific triple related to a series of similar things. So, where we have...
someURI a our:thing;
our:name "literal".
someOtherURI a our:thing;
our:name "literal".
...n
I want to specifically remove all someURI our:name "literal" triples and leave the things defined.
I know I can do this via DELETE DATA, but that requires I know all URIs first, which is too many steps in itself.
I'm struggling a bit with DELETE WHERE, but I assume the answer is something like...
DELETE{ ?uri our:name ?literal }
WHERE{ ?uri a our:thing. }
Firstly, is my DELETE WHERE sound?
Secondly, I'm wondering if it's possible to nest a SELECT query within a DELETE DATA? So...
DELETE DATA{
?uri our:name ?literal
{
SELECT ?uri
WHERE {?uri a our:thing.}
}
}
Specifically, would the subquery provide the ground triple (the URI to replace the ?uri variable, or would the no variable rule for DELETE DATA throw the error first? It seems obvious, but I've been wondering and can't test it out on my triplestore. I'm using OWLIM-SE.

Firstly, is my DELETE WHERE sound?
Almost, but not quite. A DELETE clause can not contain any variables that are not bound in the WHERE clause (the variable ?literal, in your case). So you need to modify it slightly, like so:
DELETE {
?uri our:name ?literal .
}
WHERE {
?uri a our:thing;
our:name ?literal .
}
Secondly, I'm wondering if it's possible to nest a SELECT query within
a DELETE DATA?
That is not possible. A DELETE DATA operation can only contain fixed RDF triples - no variables and certainly no subqueries.
However, you can use a nested SELECT in a DELETE WHERE operation if you want. So the following is legal:
DELETE {
?uri our:name ?literal .
}
WHERE {
{ SELECT ?uri ?literal
WHERE { ?uri a our:thing;
our:name ?literal .
}
}
}
It doesn't really give you any advantage to do this though, in your particular case: this update expresses exactly the same thing as the first one, just in a more roundabout way.

Related

Removing all predicates of a given subject via SPARQL

I am trying to delete a known URI from our triplestore. It can be a subject or an object, by its predicates. So what I like to do is the following:
DELETE {
GRAPH <graph> {
<uri> ?p1 ?o1 .
?s2 ?p2 <uri> .
}
}
By executing the following query, all occurences of the known should be removed in the known . However I cannot use variables in a delete function. How can I make the above code working?
DELETE needs a template 9what to delete) and a pattern (binds variables).
There is the DELETE WHERE operation. https://www.w3.org/TR/sparql11-update/#deleteWhere
DELETE WHERE { .... is a short form of DELETE {...} WHERE {...} with the same {...} for template and pattern.

Marklogic: How can we perform the case-insensitve search in a pure SPARQL query?

I have a scenario where i am trying to find the content using the SPARQL query for the triples stored in marklogic. The filter condition in SPARQL query needs to perform the case-insensitve search for a particular term. May i know how can i do that?
For eg:
filter(strstarts(?personName, "FA"^^xs:string))
The above filters should fetch me the results whose personName value starts with upperCase also(like: fa). I think this will clearly give some idea about the issue i am asking about.
I believe you have two options to do case-insensitive search using SPARQL in MarkLogic.
If you want to use SPARQL only than you can do the following (modify the select statement as needed):
select * where {
?personName ?p ?o
FILTER (lcase(str(?personName)) = "fa"^^xs:string)
}
As an alternative you could also mix some fn:* functions with your SPARQL statement so you could do something similar to:
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select * where {
?personName ?p ?o
FILTER (?personName, fn:lower-case("FA"))
}
Don't forget that in MarkLogic you can use any fn:* or cts:* function as well (the prefix for cts:* functions would be prefix cts: <http://marklogic.com/cts#>
I hope this helps.
Next to the good suggestions of Tamas, there is also REGEX. It accepts a case-insensitivity flag. Something like:
select * where {
?personName ?p ?o
FILTER( regex(str(?personName), "^fa", "i") )
}
HTH!

SPARQL query in DBpedia Sorql return no results

I tried to run SPARQL query from the book Learning SPARQL of Bob DuCharme. I runned it on http://dbpedia.org/snorql:
SELECT ?elvisbday WHERE {
<http://dbpedia.org/resource/Elvis_Presley>
<http://dbpedia.org/property/dateOfBirth> ?elvisbday .
}
But the result is an empty output. I checked that URIs are correct. So what's my error? Do I need to add some specific PREFIX?
You got the property wrong. Try this:
SELECT ?elvisbday WHERE {
<http://dbpedia.org/resource/Elvis_Presley>
<http://dbpedia.org/ontology/birthDate> ?elvisbday .
}
In the future, you might want to explore the properties that describe the resource in the endoint if you don't find what you are looking for. You may use this query for that:
SELECT ?p ?o WHERE {
<http://dbpedia.org/resource/Elvis_Presley> ?p ?o
}

How to retrieve abstract for a DBpedia resource?

I need to find all DBpedia categories and articles that their abstract include a specific word.
I know how to write a SPARQL query that queries the label like the following:
SELECT ?uri ?txt WHERE {
?uri rdfs:label ?txt .
?txt bif:contains "Machine" .
}
but I have not figured out yet how to search the abstract.
I've tried with the following but it seems not to be correct.
SELECT ?uri ?txt WHERE {
?uri owl:abstract ?txt .
?txt bif:contains "Machine" .
}
How can I retrieve the abstract in order to query its text?
Since you already know how to search a string for text content, this question is really about how to get the abstract. If you retrieve any DBpedia resource in a web browser, e.g., http://dbpedia.org/resource/Mount_Monadnock (which will redirect to http://dbpedia.org/page/Mount_Monadnock), you can see the triples of which it's a subject or predicate. In this case, you'll see that the property is dbpedia-owl:abstract. Thus you can do things like
select * where {
?s dbpedia-owl:abstract ?abstract .
?abstract bif:contains "Monadnock" .
filter langMatches(lang(?abstract),"en")
}
limit 10
SPARQL results
Instead of visiting the page for the resource, which not endpoints will support, you could have simply retrieved all the triples for the subject, and looked at which ones relate it to its abstract. Since you know the abstract is a literal, you could even restrict it to triples where the object is a literal, and perhaps with a language that you want. E.g.,
select ?p ?o where {
dbpedia:Mount_Monadnock ?p ?o .
filter ( isLiteral(?o) && langMatches(lang(?o),'en') )
}
SPARQL results
This also clearly shows that the property you want is http://dbpedia.org/ontology/abstract. When you have a live query interface that you can use to pull down arbitrary data, it's very easy to find out what parts of the data you want. Just pull down more than you want at first, and then refine to get just what you want.

How to create a small SPARQL query for DBpedia?

I'm a SPARQL beginner, I would like to know how to create this small query in SPARQL from DBpedia:
The query is: Getting the topics of a thing (name of person, organisation …)
SELECT DISTINCT ?occupation WHERE {
?s <w3.org/2000/01/rdf-schema#label>; 'Madonna'#en . ?occupation dbpedia-owl:occupation ?s
}
So I create this query to get the occupation of Madonna, is this correct? In this case Madonna but it could be anything else.
I tried this query but i think this is wrong:
SELECT DISTINCT ?occupation WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#label> 'Madonna'#en .
?s dbpedia-owl:occupation ?occupation
}
I tried this too i think it's correct:
PREFIX res: <http://dbpedia.org/resource/>
SELECT DISTINCT ?string
WHERE {
res:Tom_Cruise dbpprop:occupation ?string .
}
It works with Tom_Cruise but not with Madonna or barack_Obama for example.
A query like your attempt is a good start:
PREFIX res: <http://dbpedia.org/resource/>
SELECT DISTINCT ?string
WHERE {
res:Tom_Cruise dbpprop:occupation ?string .
}
Now that we've got something specific to work from, we can look at the specific problems that it might have. First, I'm going to rewrite it using the same namespace prefixes that the public endpoint web interface supports, so that we can copy and paste to it. I'm also putting the keywords in lower case because I don't like yelling.
select distinct ?string where {
dbpedia:Tom_Cruise dbpprop:occupation ?string .
}
SPARQL results
Now, you mentioned that
It works with Tom_Cruise but not with Madonna or barack_Obama, for example.
All the data in DBpedia is publicly available for you to browse. If you want to see why there are no results for Madonna, note that dbpedia:Madonna is shorthand for http://dbpedia.org/resource/Madonna and pull up that page in your browser. From the properties listed on that page, you'll see that it's a redirection page (indeed, you'll see the same thing if you go to the corresponding Wikipedia article, http://en.wikipedia.org/wiki/Madonna). You want the IRI http://dbpedia.org/resource/Madonna_(entertainer). Unfortunately, you can't write that directly in a SPARQL query because of the parentheses, so you have to write
select distinct ?string where {
<http://dbpedia.org/resource/Madonna_(entertainer)> dbpprop:occupation ?string .
}
SPARQL results
Now, there are a couple of problems with barack_Obama: (i) the capitalization needs to be Barack_Obama if you want any results. If you visit http://dbpedia.org/resource/Barack_Obama, though, you'll see that there's no dbpprop:occupation property. There's not much you can do about that; you can't query for data that isn't there. The data that is there that might be useful to you (and of a similar nature) would be dbpedia-owl:office, and dbpedia-owl:profession. For instance
select distinct ?string where {
dbpedia:Barack_Obama (dbpedia-owl:office|dbpedia-owl:profession) ?string .
}
SPARQL results