0

For example, if I want to find number of hops between Politician (Q82955) and President of the US (Q11696), the answer should be 2.

POTUS (Q11696) – subclassOf -> HeadOfGovernment (Q2285706) – subclassOf -> Politician (Q82955)

How can I write a query for this? I know I need to use count but I don't know how.

  • not **efficiently** possible in SPARQL, sorry - you have to use some other graph traversal language for this. There are workarounds with SPARQL, but those do not scale and do not work once you have multiple paths. The Wikidata dataset is free for download, use it with some more appropriate framework for your use case. Other than that, *property paths* in SPARQL would be the way to go. – UninformedUser Mar 14 '21 at 10:27
  • the most comprehensive answer to your question is here:https://stackoverflow.com/a/18032019/4744359 – UninformedUser Mar 14 '21 at 10:30
  • also, in your example there are multiple paths. when using a query like `select * { wd:Q11696 wdt:P279* ?mid . ?mid wdt:P279 wd:Q82955 }` you won't get all paths for obvious reasons – UninformedUser Mar 14 '21 at 10:37
  • or you can use non-standard SPARQL feature of Blazegraph, dubbed GAS API: `select * { SERVICE gas:service { gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ; gas:in wd:Q11696 ; gas:target wd:Q82955 ; gas:linkType wdt:P279 ; gas:out ?out ; gas:out1 ?depth ; gas:maxIterations 4 ; gas:maxVisited 2000 . } }` and post-process this somehow – UninformedUser Mar 14 '21 at 11:29
  • you can also apply fancy visualization: `#defaultView:Graph PREFIX gas: SELECT ?item ?itemLabel ?linkTo ?linkToLabel { SERVICE gas:service { gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ; gas:in wd:Q11696 ; gas:target wd:Q82955 ; gas:linkType wdt:P279 ; gas:out ?item ; gas:out1 ?depth ; gas:maxIterations 4 ; gas:maxVisited 2000 . } OPTIONAL { ?item wdt:P279 ?linkTo } SERVICE wikibase:label {bd:serviceParam wikibase:language "en" } } ` – UninformedUser Mar 14 '21 at 11:40
  • @UninformedUser - Thank you SO much! This really helps. I think your Blazegraph suggestion is very close to what I'm looking for. Would you know if I could use a property path in a link type? I see you've put "wdt:P279" as the linkType, but is there any way I could use "wdt:P31/wdt:P279*"? (one "instance-of" and then any number of "subclass of" statements) – Karan Praharaj Mar 15 '21 at 20:58
  • I don't think this is supported, see the docs: https://github.com/blazegraph/database/wiki/RDF_GAS_API#running-gas-programs - But what we can do is to omit the link type, but filter afterwards: – UninformedUser Mar 16 '21 at 08:10
  • `#defaultView:Graph PREFIX gas: SELECT ?item ?itemLabel ?linkTo ?linkToLabel (?linkType as ?edgeLabel) { SERVICE gas:service { gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ; gas:in wd:Q11696 ; gas:target wd:Q82955 ; gas:out ?item ; gas:out1 ?depth ; gas:maxIterations 4 ; gas:maxVisited 2000 . } ?item ?linkType ?linkTo filter(?linkType in (wdt:P31, wdt:P279)) SERVICE wikibase:label {bd:serviceParam wikibase:language "en" } }` – UninformedUser Mar 16 '21 at 08:11
  • with property labels: `#defaultView:Graph PREFIX gas: SELECT ?item ?itemLabel ?linkTo ?linkToLabel ?wdLabel (?wdLabel as ?edgeLabel) { SERVICE gas:service { gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ; gas:in wd:Q11696 ; gas:target wd:Q82955 ; gas:out ?item ; gas:out1 ?depth ; gas:maxIterations 4 ; gas:maxVisited 2000 . } ?item ?linkType ?linkTo filter(?linkType in (wdt:P31, wdt:P279)) SERVICE wikibase:label {bd:serviceParam wikibase:language "en" } ?wd wikibase:directClaim ?linkType . }` – UninformedUser Mar 16 '21 at 08:18
  • note, this is just an upper bound as we do get nodes in between source and target, but gather all outgoing edges of those nodes – UninformedUser Mar 16 '21 at 08:30

0 Answers0