user765160
user765160

Reputation: 25

Querying DBPedia using SPARQL to find subjects with same objects

I am trying to find all those resources from dbpedia for eg rdf:type person who have same object eg date of birth.? I thought of doing it with subquery but its definitely not the solution. Can anyone provide some useful pointer?

Upvotes: 0

Views: 1191

Answers (4)

user205512
user205512

Reputation: 8888

From what you describe I think you mean:

prefix dbp: <http://dbpedia.org/property/>
prefix foaf: <http://xmlns.com/foaf/0.1/>

select ?s1 ?s2 ?dob
where {
    ?s1 a foaf:Person ; dbp:birthDate ?dob . # Find a person, get their dob
    ?s2 a foaf:Person ; dbp:birthDate ?dob . # Find a person with the same dob
}

Adjust type and predicate to suit.

This will include some redundancy: you will find answers where the subjects are the same ('Napoleon' 'Napoleon') and get answers twice ('Daniel Dennett' 'Neil Kinnock', 'Neil Kinnock' 'Daniel Dennett'). You can remove that with a filter:

filter (?s1 < ?s2)

which just ensures that one comes before the other (however the query engine wants to do that).

prefix dbp: <http://dbpedia.org/property/>
prefix foaf: <http://xmlns.com/foaf/0.1/>

select ?s1 ?s2 ?dob
where {
    ?s1 a foaf:Person ; dbp:birthDate ?dob .
    ?s2 a foaf:Person ; dbp:birthDate ?dob .
    filter (?s1 < ?s2)
}

See the result

Upvotes: 1

William Kinaan
William Kinaan

Reputation: 28799

select * where {
?person1 a <http://dbpedia.org/ontology/Person>.
?person1 dbo:birthYear ?date.
?person2 a <http://dbpedia.org/ontology/Person>.
?person2 dbo:birthYear ?date


FILTER (?person1 != ?person2)
}
limit 10

Dbpedia will not allow you to execute that query on its public endpoint because it consumes more time that allowed, and you cannot change that time. Nevertheless, there are ways to execute it

Upvotes: 0

UninformedUser
UninformedUser

Reputation: 8465

An alternative solution to the others is using aggregate functions like in this query template

select ?o (count(distinct ?s) as ?cnt) (group_concat(distinct ?s; separator=";") as ?subjects) {
?s a <CLASS> ;
   <PREDICATE> ?o .
}
group by ?o
order by desc(count(distinct ?s))

which returns for each object the number of subjects and the list of subject belonging to a class CLASS for a given predicate PREDICATE

For example, asking for the dates of soccer players one could use

prefix dbo: <http://dbpedia.org/ontology/>
select ?date (count(distinct ?s) as ?cnt) (group_concat(distinct ?s; separator=";") as ?subjects) {
?s a dbo:SoccerPlayer ;
   dbo:birthDate ?date .
}
group by ?date
order by desc(count(distinct ?s))

Upvotes: 0

Median Hilal
Median Hilal

Reputation: 1531

A SPARQL query is basically a set of triple patterns, i.e., a join (logical AND) of queries of the form

?subject ?predicate ?object.

What you need is identical ?object. Considering that you only care about ?subject (?predicate is not of importance), you can perform such a query you by ordering the results depending on ?object. Thus you will see results sharing ?object together.

select ?s ?p ?o where {

    ?s ?p ?o.        
}
order by ?o

If you care about ?predicate as well, you should order the result using it second.

select ?s ?p ?o where {

    ?s ?p ?o.        
}
order by ?o ?p

As those couple of queries may involve too many results as they will retrieve all the results possible. I recommend filtering ?object depending on some specific criteria. For example, to select all ?subject sharing an instance of Person as their ?object, use:

select ?s where {

?s ?p ?o.
{select  ?o where{
    ?o a <http://dbpedia.org/ontology/Person>}
}
} 

Upvotes: 0

Related Questions