Is there a way in SHACL, to match only the triples of Claire?
<<ex:Bob ex:age 23>>
ex:date "2019-12-05"^^xsd:date ;
ex:author ex:Claire .
<<ex:Bob ex:age 123>>
ex:date "2019-12-06"^^xsd:date ;
ex:author ex:Bob .
Related
For a course I follow I have to write several SPARQL queries about Lego sets. I am interested in finding out if there is a Lego theme which has a single package type.
I have the following SPARQL query:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
} group by ?theme ?package_type
order by ?theme
Which produces the following output:
As you can see there is one set that has the theme “4 Juniors” and the package type “Polybag”. Now, I am interested in themes like Advanced models or Action Wheelers which only have a single package type. However, I found it challenging to filter for these themes.
What modification to my query could I implement to remove themes which have sets that have more than one package type?
This is an interesting question. I would use FILTER NOT EXISTS to add an atom to the query body, where we make sure that the theme doesn't have two types of packages, like this:
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
Thus your full query should be something like:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
} group by ?theme ?package_type
order by ?theme
You could also use the aggregation approach mentioned in the comments, but hopefully this one solves your problem.
I would like to search court cases based on their short title, but I've noticed in the RDF records that this information is sometimes stored under one property (cdm:expression_case-law_parties) and sometimes under another (cdm:expression_title_alternative). I would like to filter on both simultaneously. The below query, where I'm trying to use an OR || in the FILTER) does not work. What is the appropriate way?
PREFIX cdm: <http://publications.europa.eu/ontology/cdm#>
SELECT ?work ?expression ?ecli ?celex ?alttitle ?parties ?title
WHERE {
?work a ?class.
?expression cdm:expression_belongs_to_work ?work.
?expression cdm:expression_title ?title.
?expression cdm:expression_uses_language <http://publications.europa.eu/resource/authority/language/ENG>.
?work cdm:case-law_ecli ?ecli.
?work cdm:resource_legal_id_celex ?celex.
OPTIONAL{?expression cdm:expression_case-law_parties ?parties}
OPTIONAL{?expression cdm:expression_title_alternative ?alttitle}
FILTER(?class in (<http://publications.europa.eu/ontology/cdm#judgement>))
FILTER CONTAINS (?alttitle, "France v Commission") || (?parties, "France v Commission")}
LIMIT 15
From Stanislav Kralin's comment:
FILTER (CONTAINS (?alttitle, "France v Commission") || CONTAINS(?parties, "France v Commission"))
I am using jena-fuseki server. Suppose for example my default graph has the following triples.
#prefix bprefix: <http://raghav/Rathi#>
bprefix:title71 a bprefix:Title ;
bprefix:fromCountry bprefix:UnitedStates ;
bprefix:hasCast bprefix:BobbyMoynihan , bprefix:DemetriMartin , bprefix:EricEdelstein ;
bprefix:hasDateAdded "September 30, 2018" ;
bprefix:hasDescription "Grizzly, Panda and Ice Bear are three adopted bear brothers struggling against their animal instincts to fit into the civilized, modern human world." ;
bprefix:hasDuration "1 Season" ;
bprefix:hasID "80116921"^^xsd:int ;
bprefix:hasRating bprefix:TV-Y7 ;
bprefix:hasReleaseyear "2017"^^xsd:int ;
bprefix:hasTitle "We Bare Bears" ;
bprefix:hasType bprefix:TVShow ;
bprefix:isListedin bprefix:TVComedies , <http://raghav/Rathi#Kids'TV> .
bprefix:title84 a bprefix:Title ;
bprefix:fromCountry bprefix:UnitedKingdom ;
bprefix:hasCast bprefix:PaulHollywood ;
bprefix:hasDateAdded "September 29, 2017" ;
bprefix:hasDescription "Gear up for a fast-paced journey as celebrity chef and avid auto enthusiast Paul Hollywood takes in the cars and culture of France, Italy and Germany." ;
bprefix:hasDuration "1 Season" ;
bprefix:hasID "80199032"^^xsd:int ;
bprefix:hasRating bprefix:TV-14 ;
bprefix:hasReleaseyear "2014"^^xsd:int ;
bprefix:hasTitle "Paul Hollywood's Big Continental Road Trip" ;
bprefix:hasType bprefix:TVShow ;
bprefix:isListedin bprefix:BritishTVShows , bprefix:Docuseries , bprefix:InternationalTVShows .
bprefix:title28 a bprefix:Title ;
bprefix:fromCountry bprefix:UnitedStates ;
bprefix:hasDateAdded "September 7, 2018" ;
bprefix:hasDescription "Women whO ve been sexually brutalized in war-torn Congo begin to heal at City of Joy, a center that helps them regain a sense of self and empowerment." ;
bprefix:hasDirector bprefix:MadeleineGavin ;
bprefix:hasDuration "77 min" ;
bprefix:hasID "80203094"^^xsd:int ;
bprefix:hasRating bprefix:TV-MA ;
bprefix:hasReleaseyear "2018"^^xsd:int ;
bprefix:hasTitle "City of Joy" ;
bprefix:hasType bprefix:Movie ;
bprefix:isListedin bprefix:Documentaries .
Now I want to move the triples where title hasReleaseyear>2015 from this default graph to a named graph http://example.org/mynamedgraph.
I can construct the triples that I want to move using
CONSTRUCT {?title ?predicate ?object} WHERE{
?title ?predicate ?object.
?title bprefix:hasReleaseyear ?year FILTER(?year>2015)
}
What I could look online was that MOVE operation will move "all" the triples from default to this named graph. How can I filter the triples before moving them from default graph to named graph.
I would like to store a large number of integers in an rdf database (Blazegraph). Those values need to be updated (incremented) with new data, or if missing, created. What's the best way to do that in sparql 1.1? If I was wrtiting it in SQL (MySQL/MariaDB), it would be this, assuming the database is empty at first, and the table's unique key is set to "s,p" (subject and predicate):
-- Inserting or adding A=10, B=1
INSERT INTO tbl (s,p,o) VALUES ('A','cnt',10), ('B','cnt',1)
ON DUPLICATE KEY UPDATE o=o+VALUES(o);
Resulting RDF data:
:A :cnt 10 .
:B :cnt 1 .
Next run:
-- Inserting or adding A=3, C=5
INSERT INTO tbl (s,p,o) VALUES ('A','cnt',3), ('C','cnt',5)
ON DUPLICATE KEY UPDATE o=o+VALUES(o);
Resulting RDF data:
:A :cnt 13 .
:B :cnt 1 .
:C :cnt 5 .
So the question is - how would one construct a SPARQL query to do bulk UPSERT based on existing data and increments, and make it efficient.
PREFIX : <http://example.org/>
DELETE { ?letter :cnt ?outdated }
INSERT { ?letter :cnt ?updated }
WHERE {
VALUES (?letter ?increment) { (:A 10) (:B 1) }
OPTIONAL { ?letter :cnt ?outdated }
BIND ((IF(BOUND(?outdated), ?outdated + ?increment, ?increment)) AS ?updated)
}
I am querying a large data set (temperatures recorded hourly for nearly 20 years) and I'd rather get a summary, e.g. daily temperatures.
An example query is here:
http://www.boisvert.me.uk/opendata/sparql_aq+.html?pasteid=hu5rbc7W
PREFIX opensheff: <uri://opensheffield.org/properties#>
select ?time ?temp where {
?m opensheff:sensor <uri://opensheffield.org/datagrid/sensors/Weather_Mast/Weather_Mast.ic> ;
opensheff:rawValue ?temp ;
<http://purl.oclc.org/NET/ssnx/ssn#endTime> ?time .
FILTER (str(?time) > "2011-09-24")
}
ORDER BY ASC(?time)
And the results look like this:
time temp
"2011-09-24T00:00Z" 12.31
"2011-09-24T01:00Z" 11.68
"2011-09-24T02:00Z" 11.92
"2011-09-24T03:00Z" 11.59
Now I would like to group by a part of the date string, so as to get a daily average temperature:
time temp
"2011-09-24" 12.3 # or whatever
"2011-09-23" 11.7
"2011-09-22" 11.9
"2011-09-21" 11.6
So, how do I group by a substring of ?time ?
Eventually solved it. Running here:
http://www.boisvert.me.uk/opendata/sparql_aq+.html?pasteid=j8m0Qk6s
Code:
PREFIX opensheff:
select ?d AVG(?temp) as ?day_temp
where {
?m opensheff:sensor <uri://opensheffield.org/datagrid/sensors/Weather_Mast/Weather_Mast.ic> ;
opensheff:rawValue ?temp ;
<http://purl.oclc.org/NET/ssnx/ssn#endTime> ?time .
BIND( SUBSTR(?time, 1, 10) AS ?d ) .
}
GROUP BY ?d
ORDER BY ASC(?d)
We use BIND to set a new variable to the substring required, and then grouping and averaging by that variable is simple enough.