SPARQL filter results dates only - sparql

I'm trying to find all results that are dates, regardless of the properties they're describing. This FILTER query gives me the results I want:
PREFIX mydb: <http://mydb.org/schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?s ?p ?date
WHERE {
?s ?p ?date .
FILTER (?date > "1800-01-01"^^xsd:date)
}
But it only works because I set a bottom limit earlier than my earliest date. Is there a way to use a boolean filter for the xsd:date datatype, similar to isURI()?

FILTER ( datatype(?date) = xsd:date ) is the filter I needed.
Thanks to Stanislav Kralin for his comment.

Related

Excluding triples based on substring

I have a graph created by sponging web pages. I'm trying to write a query to exclude all triples where the subject is a web page. I can get these triples simply by
FILTER (STRENDS((STR(?i)), "html"))
but what's the best way to exclude them. Basically I need all {?s ?p ?o} minus the subset {?i ?p ?o}.
This
SELECT *
{ ?s ?p ?o
FILTER ( ! STRENDS( STR(?s), "html") )
}
filters the outcome the pattern.

SPARQL - Return mutual objects of a list of subjects

How can i get all predicates + objects, which are shared by a list of subjects - without knowing anything about the predicates/objects of these subjects?
Let's look at this example query from Wikidata:
SELECT ?chancellor WHERE{
?chancellor wdt:P39 wd:Q4970706. #P39 = position held, Q4970706 = Chancellor of Germany
}
Link to this query.
This query returns all former chancellors of germany.
Now i want to return every predicate + object, which every chancellor has in common e.g. every of the subjects is an instance of human, is born in Germany and whatever.
I guess this is an easy one. However i have no idea.
This is a good one. Here's a near-hit:
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
select ?p ?o (count(distinct ?chancellor) as ?cs) where {
?chancellor wdt:P39 wd:Q4970706.
?chancellor ?p ?o .
}
group by ?p ?o
order by desc(?cs)
Link to query
This takes all chancellors, and their properties and values. It counts the number of chancellors per prop/val.
By ordering that you can see the most common prop / vals at the top.
Now what you want is the only the results for all chancellors. We can get the number of chancellors in one query easily enough, and stick the two together:
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
select ?p ?o where {
{
# Find number of chancellors
select (count(?chancellor) as ?num_chancellors) where {
?chancellor wdt:P39 wd:Q4970706
}
}
{
# Find number of chancellors per predicate / value
select ?p ?o (count(distinct ?chancellor) as ?chancellor_count) where {
?chancellor wdt:P39 wd:Q4970706.
?chancellor ?p ?o .
}
group by ?p ?o
}
# Choose results all chancellors share
filter (?num_chancellors = ?chancellor_count)
}
Link to query.
I think this does what you want. Not very pretty, I confess.
An interesting aspect of SPARQL and RDF is that you don't need to know anything about the data to query it. In your case I'd suggest adding the triple pattern ?chancellor ?p ?o . and select ?p and ?o. From there you can choose any property you're looking for. Be sure to use OPTIONAL if some of the ?chancellor matches don't have that property value.

Querying for date range in SPARQL

I have some data in a semantic database that looks like the following, where the first column is the ID of an object, and the second column is the last modified date, as xsd:dateTime's.
?s ?last_mod_date
http://company.com/custom.xml#obj1, 2016-08-30T08:44:49.000-04:00
http://company.com/custom.xml#obj2, 2016-08-30T17:24:21.000-04:00
http://company.com/custom.xml#obj3, 2016-08-30T09:03:57.000-04:00
http://company.com/custom.xml#obj4, 2016-07-27T03:26:44.000-04:00
http://company.com/custom.xml#obj5, 2016-08-11T03:23:53.000-04:00
http://company.com/custom.xml#obj6, 2016-07-19T03:05:03.000-04:00
I'm trying to filter this list of objects down to one item by date; my query input is unfortunately only precise to the minute, so I'm trying to use a date range to find the object, like this:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix cust: <http://company.com/custom.xml#>
SELECT ?s ?date WHERE
{
?s cust:last_mod_date ?date.
BIND("2016-08-30T09:03:00.000-0400"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?minDate).
BIND("2016-08-30T09:04:00.000-0400"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?maxDate).
FILTER(?date > ?minDate && ?date < ?maxDate)
}
The above query should find obj3, but instead it finds nothing. This is with a Sesame semantic database. Any ideas why this would be?
Your datetimes in the SPARQL query are malformed:
BIND("2016-08-30T09:03:00.000-0400"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?minDate).
BIND("2016-08-30T09:04:00.000-0400"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?maxDate).
Should be
BIND("2016-08-30T09:03:00.000-04:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?minDate).
BIND("2016-08-30T09:04:00.000-04:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> as ?maxDate).
The timezone modifier is the first BIND statements are missing a colon.

sparql to retrieve the value of a min constraint

How can I retrieve a min constraint on a class' attribute using sparql? I have value min 1000 decimal, and I would like to get 1000
In a hypothetical world that you have such a statement:
Class: X subClassOf: hasObjectProperty min 1 Y
If you write a SPARQL query as:
SELECT *
WHERE {
?s rdfs:subClassOf ?o.
}
You must extract all the refs:subClassOf axioms. However, if you need to precise and know which ones have cardinality restrictions, you need to go further:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <http://example.com#>
SELECT *
WHERE {
?s rdfs:subClassOf ?o.
?o ?x ?y.
filter(?s = :X)
}
Among others, you can see the following result:
As you can see, there are 2 relevant items, one is Y and one is the number presented as a non-negative integer. Therefore, one way to get each item is to put a filter for ?x in the SPARQL query and get each one one by one out. For example, filter owl:onClass will give you ?y:
prefix : <http://example.com#>
SELECT *
WHERE {
?s rdfs:subClassOf ?o.
?o owl:onClass ?y.
filter(?s = :X)
Here is the sparql query I used following Artemis' answer
SELECT ?min
WHERE {?s rdfs:subClassOf ?o.
?o owl:minQualifiedCardinality ?min.
FILTER(?s = :value) }
And with jena, I use getLiteral("min").getFloat();

Protégé Date filter not working

I have a simple query with simple results but when I try to apply a filter on the date, I get no results.
Initial query and result :
SELECT DISTINCT ?projet ?date
WHERE { teluq:Gilbert_Paquette foaf:pastProject ?projet.
?gilbert foaf:familyName ?paquette.
?projet db:projectEndDate ?date.
}
Results are of the form : "2012-06-30"^^<http://www.w3.org/2001/XMLSchema#date>
but when I add my filter, I get nothing.
SELECT DISTINCT ?projet ?date
WHERE { teluq:Gilbert_Paquette foaf:pastProject ?projet.
?gilbert foaf:familyName ?paquette.
?projet db:projectEndDate ?date.
FILTER (?date < "2014-11-04"^^xsd:date)
}
I'm using Protégé on an imported turtle file.
Am I missing something?
Thanks
This works :
PREFIX teluq: <http://exemple.teluq.ca/ressources/>
PREFIX db: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?collab ?projet ?date
WHERE { teluq:Gilbert_Paquette foaf:pastProject ?projet.
?gilbert foaf:familyName ?paquette.
?projet db:projectEndDate ?date.
?collab foaf:pastProject ?projet.
FILTER (?date < "2014-11-08"^^xsd:date)
}
ORDER BY ?projet
But thanks for the help
§ 17.3 Operator Mapping of the SPARQL 1.1 standard specifies how the < operator is
defined for SPARQL (modulo operator extensions), and while it defines the behavior on xsd:dateTimes, it doesn't specify anything about xsd:dates, so its quite possible that the filter expression simply returns false. However, xsd:dates should be comparable using their lexical forms, so you should be able to do
#-- when ?date is an xsd:date, compare its lexical form with "2014-11-04".
filter (datatype(?date) = xsd:date && str(?date) < "2014-11-04")