-
Notifications
You must be signed in to change notification settings - Fork 31
Multi‐value placeholders
Grlc queries usually work with one-on-one variable-value replacement. But there are instances in which you would like to replace multiple values into the same variable. This tutorial shows you how to achieve this.
For example the following example query creates an API which queries for albums of artists of a specific genre:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX schema: <http://schema.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?band ?album WHERE {
?band rdf:type dbo:Band .
?album rdf:type schema:MusicAlbum .
?band dbo:genre ?_genre_iri .
?album dbp:artist ?band .
} LIMIT 100
For example you could query for rock bands (replacing genre for http://dbpedia.org/resource/Rock_music) producing a list of rock bands and albums or you could query for alternative rock bands (replacing genre for http://dbpedia.org/resource/Alternative_rock) producing a list of alternative rock bands and albums
But there are instances in which you would like to replace multiple values into the same variable. For example, if you wanted to create a list of two genres (or three or four...), then you would need a different query. This can be accomplished using some crafty SPARQL.
For this example, lets try to create a list with rock and alternative rock bands.
You could use a query like this:
#+ summary: Multi-value placeholder hack
#+ endpoint: https://dbpedia.org/sparql
#+ defaults:
#+ - placeholder: http://dbpedia.org/resource/Alternative_rock http://dbpedia.org/resource/Rock_music
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX schema: <http://schema.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?band ?album ?genre WHERE {
#=================== MULTI-VALUE PLACEHOLDER ====================#
{ select ?genreliteral { # <- VAR genreliteral
bind(?_placeholder as ?v) # <- VAR _placeholder
{select*{optional{?a ?b ?c}}limit 1} # (for some Virtuoso v.) #
values ?x{0 1 2 3 4 5 6 7 8 9} values ?y{0 1 2 3 4 5 6 7 8 9} #
bind((10*?x)+?y as ?n) # (works for a maximum of 100 values) #
bind(" " as ?sep) # (separator as regex-compatible character) # <- CONST sep
bind(concat("^([^",?sep,"]*",?sep,"){",str(?n),"}") as ?p) #
bind(concat(?sep,".*") as ?p0) #
filter(if(?n=0,true,regex(?v,?p))) # (=0 check for Virtuoso) #
bind(replace(if(?n=0,?v,replace(?v,?p,"")),?p0,"") as ?genreliteral) # <- VAR genreliteral
} } #
#================================================================#
# The genreliteral is a literal. You can make a URI out of it like this:
bind(uri(?genreliteral) as ?genre)
#================================================================#
?band rdf:type dbo:Band .
?album rdf:type schema:MusicAlbum .
?band dbo:genre ?genre .
?album dbp:artist ?band .
} LIMIT 100
The variable ?_placeholder
takes a literal of space-separated IRIs, which are then bound individually in the query. It has an upper limit of 100 IRIs.
This query creates an API with could produce our desired list of will produce producing a list of rock and alternative rock bands and albums
Although this is not (strictly speaking) a functionality that grlc provides, we thought this method could be useful for many grlc users.
Thanks to @tkuhn for contributing this method!