Alternatives to the OPTIONAL fallback SPARQL patte

2019-07-22 16:06发布

问题:

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?

回答1:

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)
}


回答2:

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}
} 


回答3:

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.



标签: sparql