I need to retrieve a single image for each resource in a target set, testing multiple non-exclusive predicates with a priority order.
I'm currently using a standard OPTIONAL fallback pattern along the lines of
select ?r ?i where {
?r a dbo:Automobile .
optional { ?r <http://dbpedia.org/ontology/thumbnail> ?i }
optional { ?r <http://xmlns.com/foaf/0.1/depiction> ?i }
optional { ?r <http://xmlns.com/foaf/0.1/logo> ?i }
optional { ?r <http://schema.org/image> ?i }
}
but this approach is turning out to be troublesome on some backends: is anyone aware of any simple/efficient alternative?
What's the problem with the optionals? The repeated use of ?i
?
A different approach is to get each alternative and pick the first one set.
select ?r ?i where {
?r a dbo:Automobile .
optional { ?r <http://dbpedia.org/ontology/thumbnail> ?i1 }
optional { ?r <http://xmlns.com/foaf/0.1/depiction> ?i2 }
optional { ?r <http://xmlns.com/foaf/0.1/logo> ?i3 }
optional { ?r <http://schema.org/image> ?i4 }
BIND(COALESCE(?i1,?i2,?i3,?i4) AS ?i)
}
I think you just need to filter you predicates. Something like this might help:
prefix schema:<http://schema.org/>
prefix foaf:<http://xmlns.com/foaf/0.1/>
prefix dbpedia-owl:<http://dbpedia.org/ontology/>
select distinct ?r ?i
where {
?r a dbpedia-owl:Automobile .
?r ?p ?i.
values ?p { foaf:logo foaf:depiction dbpedia-owl:thumbnail schema:image}
}
Golfing here from Artemis original, the problem is the ordering of the predicates. So rather than simple values we could use the following:
values (?p ?pref) {
(dbpedia-owl:thumbnail 1)
(foaf:depiction 2)
(foaf:logo 3)
(schema:image 4)
}
Now we can choose by order:
prefix schema:<http://schema.org/>
prefix foaf:<http://xmlns.com/foaf/0.1/>
prefix dbpedia-owl:<http://dbpedia.org/ontology/>
select distinct ?r ?i
where {
?r a dbpedia-owl:Automobile .
?r ?p ?i.
values (?p ?pref) {
(dbpedia-owl:thumbnail 1)
(foaf:depiction 2)
(foaf:logo 3)
(schema:image 4)
}
}
order by ?r ?pref
That gives us almost what is required. All we then need is to group by ?r and pick the row with the largest ?pref.
Unfortunately that's not simple in SPARQL.