SPARQL query returns multiple birth dates for same person - sparql

I am learning SPARQL and dbpedia by working through the queries in https://www.joe0.com/2014/09/22/how-to-use-sparql-to-query-dbpedia-and-freebase/ . I am testing a query to return John Lennon's date of birth and I am running my queries in http://dbpedia.org/sparql . The query is:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT DISTINCT ?x0 ?x1 WHERE {
?x0 rdf:type foaf:Person.
?x0 rdfs:label "John Lennon"#en.
?x0 dbpedia-owl:birthDate ?x1.
}
It returns two rows containing the same date (9 Oct 1940). My question is: why does the query return two rows even though it uses DISTINCT? Prior to asking this question I checked the following:
Why does my SPARQL query duplicate results?
Duplicate rows when making SPARQL queries
but I don't think they explain the duplicate dates.
Edit: I converted the results to text and pasted them below
-------------------------------------- -----------------------------------------------------
x0 x1
--------------------------------------- -----------------------------------------------------
http://dbpedia.org/resource/John_Lennon 1940-10-09
http://dbpedia.org/resource/John_Lennon "1940-10-9"^^<http://www.w3.org/2001/XMLSchema#date>

As stated it seems dbpedia actually has two dates, 1940-10-09 (valid) and 1940-10-9 (invalid). The answer is to add a FILTER that converts the date to a string and only allows dates conforming to YYYY-MM-DD. Anyway it works!
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT DISTINCT ?x0 ?x1 STR(?x1) WHERE {
?x0 rdf:type foaf:Person.
?x0 rdfs:label "John Lennon"#en.
?x0 dbpedia-owl:birthDate ?x1.
FILTER (REGEX(STR(?x1),"[0-9]{4}-[0-9]{2}-[0-9]{2}")).
}

Well, it is not your fault! Simply the resource has both of these triples as you can see here. There are duplicates in the data.

I ran your query on the DBpedia endpoint and asked for the results in an RDF-based format (Turtle), and found that the lexical forms of the date literals are actually different:
"1940-10-09"^^xsd:date
"1940-10-9"^^xsd:date
The second isn't actually a legal xsd:date. The first is, which is probably why the SPARQL endpoint prints it in "pretty" fashion in the HTML table (as just 1940-10-09).

The result is a slowdown on queries because each access to an invalid date trig an exception (for example, with a query from fuseki) or the filter do the job to eliminate the wrong date, but it's costly

Related

SPARQL query cannot find page that should exist

I am writing a query in DBpedia live http://dbpedia-live.openlinksw.com/sparql/ to return details of well known people. As a test case, I know there exists a page for the Roman Emperor Nero at http://dbpedia.org/page/Nero but my query does not return a row for him. My SPARQL query is:
# Runs in live (http://dbpedia-live.openlinksw.com/sparql/)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT DISTINCT ?x0 ?name2 ?dob
WHERE {
?x0 rdf:type foaf:Person.
?x0 rdfs:label ?name.
?x0 dbo:birthDate ?dob.
FILTER REGEX(?name,"^Ner.*","i").
BIND (str(?name) AS ?name2)
} ORDER BY ?name2 LIMIT 100
I checked the page http://dbpedia.org/page/Nero and it has the rdf:type, rdfs.label and dbo.birthDate properties referenced in my query. When I run the above query it returns 100 other people with name beginning "Ner" using the case insensitive version of REGEX.
So my question is: Why does the above query not return Nero in the list of results?
First thing, note that on DBpedia, Nero (currently) comes in result rows 109 and 110, so you need at least 110 rows to see him.
Now, note that Nero's description on DBpedia-Live is different than on DBpedia -- and that neither is correct.
Of particular note, see that on DBpedia-Live, Nero's http://dbpedia.org/property/birthDate has one value -- 1937-12-15 (xsd:date) -- while on DBpedia, http://dbpedia.org/ontology/birthDate has two values -- 0037-12-15 (xsd:date) and 1937-12-15 (xsd:date).
Also note that on DBpedia-Live, Nero has no http://dbpedia.org/ontology/birthDate value -- while on DBpedia, http://dbpedia.org/property/birthDate has no value.
These results should be of interest to you -- on DBpedia, and on DBpedia-Live.

Find people linked with Person X using Sparql and DBpedia

I am new to querying DBPedia using Sparql. I would like to find people related to a person X using DBPedia.
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpr: <http://dbpedia.org/resource/>
PREFIX dbpo: <http://dbpedia.org/ontology/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT ?P
WHERE {dbpr:Chuck_Norris}
In case you want the people directly related to a person, then you need two triple patterns, one having the person as a subject and another as an object. Here is one way to construct such a query:
SELECT DISTINCT ?has ?of ?person
WHERE {
{?person a foaf:Person;
?of dbr:Chuck_Norris}
UNION
{?person a foaf:Person.
dbr:Chuck_Norris ?has ?person}
}
I'm using dbr: as this is a predefined prefix in DBpedia.
In some cases, you'll get different results if you query on http://live.dbpedia.org/sparql
Now, this query has a limitation. It will get you only relations to other DBpedia resources. Quite often there might be related persons asserted as literals. I don't know of an elegant way to get them, but one way would be to ask for a list of properties that are known to be used for person relations. Here is an example with a list with one value for dbp:spouse:
SELECT DISTINCT ?has ?of ?person
WHERE {
{?person a foaf:Person;
?of dbr:Chuck_Norris}
UNION
{?person a foaf:Person.
dbr:Chuck_Norris ?has ?person}
UNION
{values ?has {dbp:spouse}
dbr:Chuck_Norris ?has ?person .}
}
From http://live.dbpedia.org/sparql this will bring you additionally:
has | person
---------------------------------------------------------
http://dbpedia.org/property/spouse | "Dianne Holechek"#en
http://dbpedia.org/property/spouse | "Gena O'Kelley"#en
---------------------------------------------------------
In general asking for literals like that will bring you a lot of garbage results, which you can reduce using string filters.

Wikidata Query Service - Bug on the 'Whose birthday is today?' SPARQL Query Examples

I was playing with the SPARQL query examples. The query 'Whose birthday is today' always ends up in a QueryTimeoutException (Query deadline is expired).
However If I change the birthdate property P569 to the death date property P570, the query runs without throwing an exception.
Is there something to do to have the birth query successfully executed?
I think the query is possibly too heavy for the wikibase service. If you just try to get all the properties through the person's properties, you will have success. I tried the following:
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT distinct ?name (year(?date) as ?year) WHERE {
?entityS wdt:P569 ?date .
?entityS wdt:P1477 ?name.
FILTER (datatype(?date) = xsd:dateTime)
FILTER (month(?date) = month(now()))
FILTER (day(?date) = day(now()))
}

SPARQL date range

I'm trying to obtain all records between certain dates. The date field has appears in this format: 2012-01-31. I think it is of type: <http://www.w3.org/2001/XMLSchema#date>
How would I modify the query below to extract records with date greater than 2012-01-31 please?
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX lrppi: <http://landregistry.data.gov.uk/def/ppi/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX lrcommon: <http://landregistry.data.gov.uk/def/common/>
SELECT ?county ?postcode ?amount ?date
WHERE
{
?transx lrppi:pricePaid ?amount .
?transx lrppi:transactionDate ?date .
?transx lrppi:propertyAddress ?addr.
?addr lrcommon:postcode "PL6 8RU"^^xsd:string .
?addr lrcommon:postcode ?postcode .
# Cant get this line to work
# ?date lrppi:transactionDate ?date . FILTER ( ?date >= "1327968000"^^xsd:date )
OPTIONAL {?addr lrcommon:county ?county .}
}
ORDER BY ?postcode
If you want to play with this, you can enter your query here:
http://landregistry.data.gov.uk/landregistry/sparql/sparql.html
This is what the FILTER clause is designed for.
The Expressions and Testing Values section of the SPARQL specification covers this in detail, pretty much the first example in that section covers filtering on dates.
Edit
If you are new to SPARQL then I would recommend you read a good SPARQL tutorial like SPARQL by Example which is written by one of the specification authors. This will walk you through various parts of SPARQL and should help you get your head around the RDF data model and query language better.
In terms of dates they are represented using XML schema datatypes, for example expressing today as a date would be the following:
"2013-03-22"^^xsd:date
The linked specification covers the lexical form of various datatypes.
So for your example it would be the following:
FILTER ( ?date >= "2012-01-31"^^xsd:date )
If you are starting from a UNIX timestamp and trying to get to an xsd:date see Generating an xsd:dateTime in shell script which may provide a useful starting point.

Can't execute a specific SPARQL query on DBPedia :/

On this site, for example, take the first SPARQL query and make something very similar:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX p: <http://dbpedia.org/property/>
SELECT *
WHERE {
?name p:name <http://dbpedia.org/resource/Olivier_Theyskens> .
}
Try to execute it: here
And I get no results. However, modify the query to the following:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX p: <http://dbpedia.org/property/>
SELECT *
WHERE {
?name p:name ?otherthing.
}
And I get results, even though they're not the results I want.
Why doesn't the first query work -- what am I doing wrong? :/
In this case, I think it's because you're ordering your query statement backwards.
The DBpedia resource (<http://dbpedia.org/resource/Olivier_Theyskens>) is the Entity or Subject (?s), the property (p:name) is the Attribute or Predicate (?p), and the value of that property (?name) is the Value or Object (?o).
SPARQL expects all statements to be { ?s ?p ?o }, but yours seems to be written as { ?o ?p ?s }...
To sum up, if you try this query --
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX p: <http://dbpedia.org/property/>
SELECT *
WHERE
{
<http://dbpedia.org/resource/Olivier_Theyskens> p:name ?name .
}
-- you'll get the results I think you want.
The problem with your first query is that p:name links to Literal and you try to match a URI.
If you want your first query to work you have to to use the property http://dbpedia.org/ontology/artist that links to the URI and not the literal:
SELECT *
WHERE {
?s <http://dbpedia.org/ontology/artist> <http://dbpedia.org/resource/The_Velvet_Underground> .
}
Notice the different name space for the property <http://dbpedia.org/ontology/artist> this namespace contains ontology instead of property - ontology is the one used for object properties.