Nicolas Raoul
Nicolas Raoul

Reputation: 60213

SPARQL recursion: Get property of class, or parent class, or grand-parent class, etc

How to get that in SPARQL?

In particular, if both cat and animal have icons, then I want to get cat's icon rather than animal's icon, because it is closer to Grumpy Cat.

If the item is an instance of several classes, or if a class is a sub-class of several classes, it would be great if all branches could be explored, and the closest icon chosen. Performance is quite important, I hope the query can run in less than a second on https://query.wikidata.org . I have tried writing a query based on imbricated MINUS clauses, but it is not really recursive.

If needed for test purposes, here are many Wikidata items with icons.

Upvotes: 1

Views: 367

Answers (1)

evsheino
evsheino

Reputation: 2277

You can't recursively look for something in SPARQL, and then stop when you find the first one. What you can do is either get all the icons, a random icon, or define a finite amount of classes that you go through.

You can use a chain of optionals to get the closest icon (in the case where you define a static depth):

# SAMPLE is used here because 1) the resource might have multiple classes,
# and 2) because of the fallback below
SELECT ?item ?itemLabel ?cls ?clsLabel (SAMPLE(?icon) AS ?icon) WHERE {
  BIND(wd:Q103474 AS ?item)
  ?item wdt:P31 ?cls.
  OPTIONAL { ?cls wdt:P2910 ?icon. }
  OPTIONAL { ?cls (wdt:P279/wdt:P2910) ?icon. }
  OPTIONAL { ?cls (wdt:P279/wdt:P279/wdt:P2910) ?icon. }
  OPTIONAL { ?cls (wdt:P279/wdt:P279/wdt:P279/wdt:P2910) ?icon. }
  # You can continue the optionals with longer property paths,
  # here we just fall back to trying the whole class path
  # (returning all icons in the path in an arbitrary order).
  OPTIONAL { ?cls (wdt:P279+/wdt:P2910) ?icon. }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?item ?itemLabel ?cls ?clsLabel

The first successful optional will bind ?icon, and so this variable will hold the "closest" icon. The SAMPLE will make sure the query only returns one icon.

Upvotes: 2

Related Questions