3

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?

A'B
  • 535
  • 3
  • 9
  • 2
    have you seen [Preference patterns for SPARQL (1.1)](http://answers.semanticweb.com/questions/20682/preference-patterns-for-sparql-11)? Most of the answers being posted here seem to variants on those older approaches. – Joshua Taylor Apr 29 '15 at 15:02
  • Alas, yes. I’m looking for a solution that is i) reasonably lightweight and ii) portable across different backends without tweaking. Unfortunately, both variations on the optional fallback pattern (with and without the use of coalesce) tend to elicit a range of backend-specific query execution bugs when `?r a dbo:Automobile` is replaced with complex, real-life patterns. I was hoping for something new on SO ;-) – A'B Apr 29 '15 at 15:57
  • Well ,the example as you've shown it is pretty much equivalent to problems that have already been answered. If there are differences in your actual problem, then they're important, and I think you're going to have to include them here in order to get different answers. – Joshua Taylor Apr 29 '15 at 16:19
  • 2
    Possible duplicate of http://stackoverflow.com/questions/29903480/matching-optional-triples-without-using-optional – Jeen Broekstra Apr 29 '15 at 21:40
  • @JeenBroekstra CONSTRUCT + post-processing sounds promising – A'B Apr 30 '15 at 06:50

3 Answers3

4

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)
}
AndyS
  • 16,345
  • 17
  • 21
  • Also, your answers to [this answers.semanticweb.com question](http://answers.semanticweb.com/questions/20682/preference-patterns-for-sparql-11) address provide some more options. – Joshua Taylor Apr 29 '15 at 15:06
  • @AndyS see my comment above – A'B Apr 29 '15 at 15:57
0

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}
} 
Artemis
  • 3,271
  • 2
  • 20
  • 33
  • I need to retrieve only the object for the first matching image predicate. Edited question to clarify query requirements. Thanks anyway. – A'B Apr 29 '15 at 13:32
  • Can you mention what is troublesome? Your question sounded like you needed a replacement, but now I'm not sure. So you only need the thubmail? So what are the rest of the optional points for? – Artemis Apr 29 '15 at 13:36
  • I understand -- A'B wants a thumbnail if present, otherwise a depiction if present, otherwise ... etc. Hence the use of ?i each time. This might be tricky because there's an order to respect (thumbnail > depiction > ...). Hmm. – user205512 Apr 29 '15 at 14:39
0

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.

user205512
  • 8,798
  • 29
  • 28
  • It's not all that difficult, but you do need to do the image selction in a subquery. You've almost reinvented the answers from [here](http://answers.semanticweb.com/questions/20682/preference-patterns-for-sparql-11/20696). – Joshua Taylor Apr 29 '15 at 15:05