how group graph pattern work in SPARQL - sparql

First of all, i don't know if this really called group graph pattern or not. Anyway,
Look at this query please
select ?x ?y where {
{?x rdf:type rs:Recommendable}
union
{?xd rs:doesntexist ?y}
}
there is no rs:doesntexist but with union i got the results only from the first sub graph which is {?x rdf:type rs:Recommendable}
but if i remove the union, so the query will be:
select ?x ?y where {
{?x rdf:type rs:Recommendable}
{?xd rs:doesntexist ?y}
}
I get empty results, may I ask you please who this work?
and the weird thing to me that this query
select ?x ?y where {
{?x rdf:type rs:Recommendable}.{}
}
works perfectly so the one before it doesnt?
Update
I think the union is like optional, I'm not sure. is it right please? (and by optional i didn't mean the optional from sparql, but i meant like when extracting the data from a union two graphs, its optional that two of them have data but if one of them is empty, we'll have the data from the other)

select ?x ?y where {
{?x rdf:type rs:Recommendable}
{?xd rs:doesntexist ?y}
}
is like (not identical) to:
select ?x ?y where {
?x rdf:type rs:Recommendable
?x rs:doesntexist ?y
}
Both patterns must match. If there is no rs:doesntexist the whole thing fails.
{}
matches all (zero) its patterns so it always works.

Related

Type of returned value in SPARQL Query

Is it possible to know the type of the return values in a SPARQL query?
For example, is there a function to define the type of ?x ?price ?p
in the following query?
SELECT DISTINCT ?x ?price ?p
WHERE {
?x a :Product .
?x :price ?price .
?x ?p ?o .
}
I want to know that
typeOf(x) = resource
typeOf(?p) = property
typeOf(?price) = property target etc.
datatype(?x)
The datatype function will tell you whether a result is a resource or a literal and in the latter case tell you which datatype it has exactly.
For example, the following query on https://dbpedia.org/sparql...
SELECT DISTINCT ?x ?code ?p datatype(?x) datatype(?code) datatype(?p)
WHERE {
?x a dbo:City.
?x dbo:areaCode ?code .
?x ?p ?o .
} limit 1
...will return:
x
code
p
callret-3
callret-4
callret-5
http://dbpedia.org/resource/Aconchi
"+52 623"
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://www.w3.org/2001/XMLSchema#anyURI
http://www.w3.org/2001/XMLSchema#string
http://www.w3.org/2001/XMLSchema#anyURI
However this will not differentiate between "resource" and "property" because a resource may be a property. What you probably mean is "individual" and "property" but even a property can be treated as an individual, for example in the triple rdfs:label rdfs:label "label".
However you can always query the rdf:type of a resource, which may give you rdf:Property, owl:DatatypeProperty or owl:ObjectProperty.

Property paths in Sparql

I am posing a Sparql query to Dbpedia endpoint with property paths:
select (COUNT(distinct ?s2) AS ?count) WHERE{
?s2 skos:broader{0,2} dbc:Countries_in_Europe
}
I want to pose the same query without property paths:
select (COUNT(distinct ?s2) AS ?count) (COUNT(distinct ?s1) AS ?count1) WHERE{
?s2 skos:broader dbc:Countries_in_Europe.
?s1 skos:broader ?s2.
}
I have two questions:
Is it possible to get ?s1+?s2 for the second query?
For the second query, I expect the sum of the count numbers +1 (dbc:Countries_in_Europe) should be the same with the first query. But they are not. What is wrong?
Thanks in advance.
You're using non-standard SPARQL, i.e. restricting the depth did not make it to the final version, see the W3C specs
I guess the first query is supposed to returns sub-categories of the given one up to a depth 2, right? Your second query doesn't do the same. You have to use a UNION of each distance, i.e. one for the direct sub-categories, and one for the other levels.
SELECT (COUNT(distinct ?s) AS ?count) WHERE {
{
?s skos:broader dbc:Countries_in_Europe
} UNION {
?s1 skos:broader dbc:Countries_in_Europe.
?s skos:broader ?s1
}
}
Note, in your first query you used {0,2} which means due to 0 distance the category dbc:Countries_in_Europe itself is also part of the result. If you need it, you should add +1 to the result of the second query.
Update
As per #JohuaTaylor's comment below, a more compact syntax would be
SELECT (COUNT(distinct ?s) AS ?count) WHERE {
?s skos:broader/skos:broader? dbc:Countries_in_Europe
}

how to remove duplicates in sparql query

I wrote this query and return list of couples and particular condition. ( in http://live.dbpedia.org/sparql)
SELECT DISTINCT ?actor ?person2 ?cnt
WHERE
{
{
select DISTINCT ?actor ?person2 (count (?film) as ?cnt)
where {
?film dbo:starring ?actor .
?actor dbo:spouse ?person2.
?film dbo:starring ?person2.
}
order by ?actor
}
FILTER (?cnt >9)
}
Problem is that some rows is duplicate.
example:
http://dbpedia.org/resource/George_Burns http://dbpedia.org/resource/Gracie_Allen 12
http://dbpedia.org/resource/Gracie_Allen http://dbpedia.org/resource/George_Burns 12
how to remove these duplications?
I added gender to ?actor but it damage current result.
Natan Cox's answer shows the typical way to exclude these kind of pseudo-duplicates. The results aren't actually duplicates, because in one, e.g., George Burns is the ?actor, and in the other he is the ?person2. In many cases, you can add a filter to require that the two things are ordered, and that will remove the duplicate cases. E.g., when you have data like:
:a :likes :b .
:a :likes :c .
and you search for
select ?x ?y where {
:a :likes ?x, ?y .
}
you can add filter(?x < ?y) to enforce an ordering between the between ?x and ?y which will remove these pseudo-duplicates. However, in this case, it's a bit trickier, since ?actor and ?person2 aren't found using the same critera. If DBpedia contains
:PersonB dbo:spouse :PersonA
but not
:PersonA dbo:spouse :PersonB
then the simple filter won't work, because you'll never find the triple where the subject PersonA is less than the object PersonB. So in this case, you also need to modify your query a bit to make the criteria symmetric:
select distinct ?actor ?spouse (count(?film) as ?count) {
?film dbo:starring ?actor, ?spouse .
?actor dbo:spouse|^dbo:spouse ?spouse .
filter(?actor < ?spouse)
}
group by ?actor ?spouse
having (count(?film) > 9)
order by ?actor
(This query also shows that you don't need a subquery here, you can use having to "filter" on aggregate values.) But the important part is using the property path dbo:spouse|^dbo:spouse to find a value for ?spouse such that either ?actor dbo:spouse ?spouse or ?spouse dbo:spouse ?actor. This makes the relationship symmetric, so that you're guaranteed to get all the pairs, even if the relationship is only declared in one direction.
It is not actual duplicates of course since you can look at it from both ways. The way to fix it if you want to is to add a filter. It is a bit of a dirty hack but it only takes on of the 2 rows that are the "same".
SELECT DISTINCT ?actor ?person2 ?cnt
WHERE
{
{
select DISTINCT ?actor ?person2 (count (?film) as ?cnt)
where {
?film dbo:starring ?actor .
?actor dbo:spouse ?person2.
?film dbo:starring ?person2.
FILTER (?actor < ?person2)
}
order by ?actor
}
FILTER (?cnt >9)
}

Finding linked topics in DBPedia using SPARQL

Consider we have these two topics:
http://dbpedia.org/page/Jason_Furman
and
http://dbpedia.org/page/London
For the first topic, Jason Furman, we can see on the property almaMater that he went to:
http://dbpedia.org/page/London_School_of_Economics
And looking at London School of Economics we see that it has London as value of the city property.
So my question is:
If we have two topics, A and B, how can we find property values of A that has topic B in any of it's properties?
select distinct ?a ?p ?y ?q ?b where {
values ?a { dbpedia:Jason_Furman }
values ?b { dbpedia:London }
?a ?p ?y .
?y ?q ?b .
}
SPARQL results
(Note that there are two results because there are two such properties: dbpprop:almaMater and dbpedia-owl:almaMater.)

SPARQL Querying Transitive different versions of arq

Basically I got a SPARQL query below which works with the arq 2.8.8 but doesn't work with arq2.8.4 as it doesnt recognise the + symbol. I really want a query which can work on the arq 2.8.4 version which is similar to the one I posted. The query I posted basically finds all items which are the sameas each other. For eg if a is the sameas b and b is the sameas c, the query returns both b and c for a.
PREFIX owl: <http://www.w3.org/2002/07/owl#> SELECT * WHERE { ?x owl:sameas+ ?y }
The feature you are using is SPARQL 1.1 and so was not supported by earlier versions of ARQ. The only way you can write a query that gets close to what you do is to do one of the following.
Union paths of different lengths
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT *
WHERE
{
{ ?x owl:sameAs ?y }
UNION
{ ?s owl:sameAs [ owl:sameAs ?y ] . }
UNION
{ ?s owl:sameAs [ owl:sameAs [ owl:sameAs ?y ] ] . }
# Repeat the above pattern up to whatever limit you want
}
Use client side code
Issue an initial query as follows:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT * WHERE { ?x owl:sameAs ?y }
Make a list of ?y values, then for each value issue a query of the form:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT * WHERE { <constant> owl:sameAs ?y }
Where you substitute <constant> for one of the values from the list each time and then add the new values of ?y to the list.
Only thing you need to be careful of with this approach is that you keep track of values for which you've already issued the second query to save you repeating queries.