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.
Related
Good day, I am using Graphdb to store some triples as seen in the image below. This particular RDF node uses a regular URI http://example/regular/uri. What I wish to do is to not only completely delete all properties attached to this node, but also delete the node itself. (with the result that http://example/regular/uri does not appear in the graph database any longer)
So far I am only able to delete all properties, but I am not able to delete the actual RDF node itself. It seemed rather simple, but the more I research online, the more this seems impossible unless clearing the complete graph.
I have tried simple "delete where" queries as shown in example 11 of SPARQL documentation. And i have also tried using simple "delete where"-queries using the wildcard operator as shown in the query below:
Is there a way to delete such RDF nodes?
Thanks in advance!
A node exists in a graph as long as there is one or more triples with that node in subject or object position. So the easiest way would be to issue two delete statements, one deleting all statements with the node in subject position and one deleting all statements with the node in object position. But if you need/want to do it with a single operation you can do that as well with filters.
Here is a sample that delete uri://node/to/delete from uri://my/graph :
DELETE { GRAPH <uri://my/graph> {
?s ?p ?o .
}}
USING <uri://my/graph>
WHERE {
{
?s ?p ?o . VALUES ?s { <uri://node/to/delete>}
} UNION {
?s ?p ?o . VALUES ?o { <uri://node/to/delete>}
}
}
Basically, I'm trying to get the 'subclasses' of this entity. For example:
I tried using --
select ?p1 where {
<http://dbpedia.org/resource/Category:Norwegian_silent_film_actors> skos:narrower ?p1 .
}
-- and --
select ?p1 where {
<http://dbpedia.org/resource/Category:Norwegian_silent_film_actors> rdfs:subclass ?p1 .
}
-- but since that's not actually its predicate, it doesn't work. Both actually return just the entity itself if a * is added after the predicate.
Is there any way of getting those objects?
It's important to remember that is skos:broader of relations are inverse skos:broader relations -- which imply but do not necessarily indicate the presence of skos:narrower statements. DBpedia doesn't have every explicit statement that might be inferred from what's there, and inference rules are not active by default.
You can use the explicit statements that do exist with queries like this, which uses the property path + for one-or-more skos:broader relationships --
select ?p1
where
{
?p1
skos:broader+
<http://dbpedia.org/resource/Category:Norwegian_silent_film_actors>
}
-- or this, which uses the property path ^ to reverse the relationship --
select ?p1
where
{
<http://dbpedia.org/resource/Category:Norwegian_silent_film_actors>
^skos:broader*
?p1
}
This is a place where inference rules might well be brought to bear. Unfortunately, there are no predefined inference rules relating skos:broader and skos:narrower, and this public endpoint does not accept ad-hoc rule additions. You could create some on a personal endpoint, whether pre-built and pre-populated with DBpedia in the cloud or otherwise.
I have two graphs, in one the literals are tagged (#de) in the other untagged. I need a join between the two. The trivial solution with a filter runs very slow.
WHERE {
?tok nlp:lemma ?lem .
?tok2 wn:form ?t .
filter (?tok2 = ?t) .
...
An improved version which works with fuseki is
WHERE {
?tok nlp:lemma ?lem .
Bind (str(?lem) as ?lems) .
?lu :orthForm ?lems .
...
I tried ?lu :xx (str(?lem)) . but this is flagged as an error. Why?
Similarly, using value ?lems {str(?lem)}.
I assume naively that the bind does not create much overhead, thus the above solution probably o.k.
Would the same approach work for searching when the language codes are different my previous question
The only thing allowed in a triple pattern are variables, URIs, literals (in object) and bnodes. Hence instead of the pattern ?lu :xx (str(?lem)), you will need to use a BIND or projection to convert the variable to a string. Taking the first example:
WHERE {
?lu :xx ?langLem .
BIND(str(?langLem) AS ?lem)
}
Or, using projection:
SELECT (str(?langLem) AS ?lem)
WHERE {
?lu :xx ?langLem .
}
I assume you are trying to use the VALUES statement in value ?lems {str(?lem)}. VALUES is normally used to bind variables to a set of values, e.g.:
VALUES ?lem { :Euclid :Gauss }
?lem rdfs:label ?label .
...binds ?lem to :Euclid and :Gauss and executes the query, returning the union of results. I.e. it is the same as:
{ :Euclid rdfs:label ?label }
UNION
{ :Gauss rdfs:label ?label }
This is my query
select *
{
?symphonies_by_composer <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Symphonies_by_composer> .
?symphony <http://purl.org/dc/terms/subject> ?symphonies_by_composer .
}
I run it over Dbpedia end point http://dbpedia.org/sparql/
it gives me many symphonies. i want to construct my triples, adding my own property, which is mo:composedBy like this:
PREFIX mo: <http:blablabla.com/mo#>
construct
{
?symphony mo:composedBy ?composer .
?symphony a mo:Symphony
}
{
?symphonies_by_composer <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Symphonies_by_composer> .
?symphony <http://purl.org/dc/terms/subject> ?symphonies_by_composer .
}
but i don't know how to get the binding for the ?composer variable.
Do you know how ?
(I'm aware that there might be no way to get it, if you think there is no way, kindly just let me know and i will pass, unfortunately, those data)
There seems to be no explicit relation in DBPedia connecting these symphonies to an actual resource that represents the composer.
A possible workaround is to extract the name of the composer from the prefLabel of the category, by snipping off the first bit ("Symphonies by"):
PREFIX mo: <http://example.com/mo#>
PREFIX dct: <http://purl.org/dc/terms/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
CONSTRUCT
{
?symphony mo:composedBy ?composer_name .
?symphony a mo:Symphony
}
WHERE
{
?symphonies_by_composer skos:broader <http://dbpedia.org/resource/Category:Symphonies_by_composer> ;
skos:prefLabel ?label .
?symphony dct:subject ?symphonies_by_composer .
BIND(SUBSTR(STR(?label), (STRLEN("Symphonies by ") + 1)) AS ?composer_name)
}
This will give you back the name of each composer as a literal value.
A second possible step is to try and reconstruct the actual IRI of the resource identifying the composer, from the name. For example, in the case of "Hans Werner Henze", the actual resource identifying the person is http://dbpedia.org/resource/Hans_Werner_Henze, so a simple further string operations or two, replacing spaces and concatenating with the dbpedia base IRI, will resolve this. However, this is brittle, as there is no guarantee that the resource exists, and even if it does, whether it actually identifies the composer (there might be more than one Hans Werner Henze, for instance).
Of course, you can expand this further by doing followup queries to verify that the resource exists and is the correct one, but it will require some additional trial and error. If the goal is simply the name of the composer, the first example query should work fine for most instances.
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.