Sparql query delete all statements - sparql

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"))
}
}

Related

SPARQL: DELETE if subject contains 1 triple and has predicate

I was wondering if anyone knew of a way to DELETE a triple based on 2 conditions:
Subject has a triple count of 1.
The only triple on the subject matches a predicate.
The obstacle I'm coming across with these 2 conditions is that in order to COUNT the number of statements on a subject, you must do GROUP BY ?s. Then you do not have the ability to filter any ?p value.
The most likely solution would be a subquery, but I am not sure how this would be structured.
I would write it like this:
DELETE { ?s ?p ?o }
WHERE {
{
SELECT ?s (COUNT(*) AS ?c) {
?s ?p ?o
}
GROUP BY ?s
}
FILTER (?c = 1)
?s ?p ?o
}
Does something like this work?
I assume that by "Subject has a triple count of 1" you mean that there is only one triple with this subject. For the case of 1, this is a bit easier since we can just check that "there does not exist another triple for the same subject."
DELETE { ?s ?p ?o }
WHERE {
?s ?p ?o
#-- the value of ?p is the predicate of interest.
#-- Alternatively, this could be a FILTER involving
#-- the variable ?p .
values ?p { <the-predicate> }
#-- There is no other triple with ?s as the subject
#-- that has a different subject or object. (I.e.,
#-- the only triple with ?s as a subject is with ?p
#-- and ?o .
filter not exists {
?s ?pp ?oo
filter (?pp != ?p || ?oo != ?o)
}
}

Find orphan nodes with SPARQL

I am trying to find orphan nodes (nodes which do not have any incoming relations) with SPARQL in a Fuseki database.
I tried several queries which all do not return correct results.
I tried the following:
Query 1 (got this from linkedIn)
select ?o ?isOrphan where { GRAPH <http://localhost:8080/catalog/-1305288727> {
?s ?p ?o .
FILTER(!isLiteral(?o))
bind(!(EXISTS {?o ?p1 ?o2}) as ?isOrphan)}}
Query 2
SELECT ?source ?s ?p ?o
WHERE { GRAPH <http://localhost:8080/catalog/-1305288727>{
?s ?p ?o .
FILTER EXISTS {?source ?p ?s } .
}
}
Query 3 - unbound variable pp in FILTER
SELECT ?source ?s ?p ?o
WHERE { GRAPH <http://localhost:8080/catalog/-1305288727>{
?s ?p ?o .
FILTER EXISTS {?source ?pp ?s } .
}
}
Any help is highly appreciated.
This query finds each entity that is the subject of any triple, and then checks that this entity is not the object of any triple.
SELECT ?orphan
FROM <http://localhost:8080/catalog/-1305288727>
WHERE {
?orphan ?p1 [] .
FILTER NOT EXISTS { ?linkingNode ?p2 ?orphan . }
}

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)
}

Restrict property from being rdf:type

In a query like this, how can I avoid ?p being bound to rdf:type?
select ?p ?c where {
<http://dbpedia.org/resource/Istance_1> ?p ?c.
<http://dbpedia.org/resource/Istance_2> ?p ?c.
}
Add a filter to your query:
select ?p ?c where {
<http://dbpedia.org/resource/Istance_1> ?p ?c.
<http://dbpedia.org/resource/Istance_2> ?p ?c.
filter( ?p != rdf:type )
}
It's typical to use the prefix dbpedia: for http://dbpedia.org/resource/, and I expect that Istance is suppose to be Instance, so with a bit of cleanup, you'll have
prefix dbpedia: <http://dbpedia.org/resource>
select ?p ?c where {
dbpedia:Instance_1 ?p ?c .
dbpedia:Instance_2 ?p ?c .
filter( ?p != rdf:type )
}
If you're copying and pasting into the public DBpedia SPARQL endpoint, you won't need to define that prefix because it, and bunch of others are predefined, but if you'll calling it some other fashion, you will need to.

How to bind a variable to a queried item in SPARQL

In this simple sparql query I get a list of subjects whose object is 42
SELECT ?v WHERE { ?v ?p 42 }
If I add ?p as a variable
SELECT ?v ?p WHERE { ?v ?p 42 }
I will get two entities per row, the subject and the predicate.
What if I wanted three entities, so including the 42? Something like:
SELECT ?v ?p ?m WHERE { ?v ?p (42 as m) }
Another variant is to use BIND, e.g.:
SELECT ?v ?p ?m
WHERE {
BIND(42 AS ?m)
?v ?p ?m
}
The BIND statement simply adds a binding for ?m, which can then be selected for the result set.
In SPARQL 1.1, you can use VALUES for this. You would write
SELECT ?v ?p ?m WHERE {
values ?m { 42 }
?v ?p ?m
}
Standard SPARQL 1.0 does not really allow that. There may be some implementation-specific extensions for doing it, though.
As a workaround, if the data contains a triple with 42 as an object literal, you can do it e.g. like this:
SELECT ?v ?p ?m { ?v ?p 42, ?m FILTER(?m=42)}
which is equivalent with
SELECT ?v ?p ?m WHERE { ?v ?p 42 . ?v ?p ?m FILTER(?m=42)}
as you can write graph patterns sharing the same subject and predicate with the comma object list notation, and the WHERE keyword is optional.
For efficiency, you want to use basic graph patterns to reduce the working triple to a smaller set and only then apply FILTER expressions to further prune the results.
You can accomplish in two ways using BINDINGS keyword as well as FILTER
Using BINDINGS
SELECT ?v ?p ?m
WHERE { ?v ?p ?m}
BINDINGS ?m {(42)}
Using FILTER
SELECT ?v ?p ?m
WHERE {
?v ?p ?m
FILTER (?m = 42)
}
select ?v ?p ?m where { ?v ?p ?m . FILTER( ?m = 42 ) }
I know this is round-about, but I believe this is doable with a subquery.
This is a useful pattern to help you work on the query in the narrow, before you let it loose on your entire dataset:
SELECT ?v ?p ?m WHERE {
{ SELECT 42 as ?m WHERE { } }
?v ?p ?m .
}