Shortest path with SPARQL and blazegraph - sparql

This code gives the descendants of Genghis Kahn up to a certain depth (as a graph which can be changed to a table) :
PREFIX bd: <http://www.bigdata.com/rdf#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wikibase: <http://wikiba.se/ontology#>
#defaultView:Graph
PREFIX gas: <http://www.bigdata.com/rdf/gas#>
SELECT DISTINCT ?depth ?item ?itemLabel ?pic #?linkTo
WHERE {
SERVICE gas:service {
gas:program gas:gasClass "com.bigdata.rdf.graph.analytics.SSSP" ;
gas:in wd:Q720 ;
gas:traversalDirection "Forward" ;
gas:out ?item ;
gas:out1 ?depth ;
gas:maxIterations 4 ;
gas:linkType wdt:P40 .
}
# OPTIONAL { ?item wdt:P40 ?linkTo }
OPTIONAL { ?item wdt:P18 ?pic }
SERVICE wikibase:label {bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
}
ORDER BY ?depth
Is it possible to modify this code in order to obtain the shortest path between Genghis Khan and a particular descendant (e.g. Baltu, Q7070636), including the persons in between and the kinds of relationship (linkType) between them? Generally: How to obtain the shortest path between two certain nodes and as the result a table with the nodes between these nodes and the kinds of relationship between all these nodes (limited to a certain depth)?

Related

Is querying the pagerank value on DBpedia no longer available?

Since the Virtuoso version is updated recently, when I try to use the query below on the public DBpedai SPARQL endpoint. The result is empty.
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbo:<http://dbpedia.org/ontology/>
PREFIX vrank:<http://purl.org/voc/vrank#>
SELECT ?s ?v
FROM <http://dbpedia.org>
FROM <http://people.aifb.kit.edu/ath/#DBpedia_PageRank>
WHERE {
?s rdf:type dbo:University.
?s vrank:hasRank/vrank:rankValue ?v.
}
ORDER BY DESC(?v) LIMIT 50
Thank you!
There is also the option to query the Wikidata endpoint via query federation and map the result to DBpedia URIs:
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX vrank: <http://purl.org/voc/vrank#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX schema: <http://schema.org/>
SELECT * WHERE {
{
SELECT DISTINCT ?uni (URI(REPLACE(str(?article), "https://en.wikipedia.org/wiki", "http://dbpedia.org/resource")) as ?dbpedia) WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?uni wdt:P31/wdt:P279* wd:Q3918.
?article schema:about ?uni .
?article schema:inLanguage "en" .
?article schema:isPartOf <https://en.wikipedia.org/> .
}
}
}
OPTIONAL {
?uni vrank:pagerank ?rank.
}
} ORDER BY desc(?rank) LIMIT 50
Just run the HDT file with the Wikidata PageRank scores locally as explained on https://github.com/athalhammer/danker-hdt-docker. The result is cleaner (no resources such as dbpedia:Physics in the result set) and the query runs in < 3 seconds.

Get Wikidata entity descriptions via SPARQL, without Wikidata label service

I found this following code snippet on opendata.stackexchange.com, which returns name and description of citizens of the US from Wikidata:
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
SELECT ?Name ?itemDescription WHERE {
?item wdt:P27 wd:Q30 .
?item rdfs:label ?Name
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
LIMIT 3
The query can be evaluated at https://query.wikidata.org/
I am trying to get a description of a particular entity, for example Q3(life). But it in this case, the labelService does not return anything.
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
SELECT ?Name ?itemDescription WHERE {
wd:Q3 rdfs:label ?Name
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
LIMIT 3
EDIT: I am using Virtuoso and therefore cannot rely on Wikidata Label Service.
I am using
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX schema: <http://schema.org/>
SELECT ?o
WHERE
{
wd:Q3 schema:description ?o.
FILTER ( lang(?o) = "en" )
}
now, since I am querying a Virtuoso Server with Full-Text-Search capabilities, and it would be better to retrieve the description with other properties in one go.

sparql exclude multiple type hierarchy

In dbpedia I select some pages with label starting 'A'. Here I'm using additional filter by subject to narrow the set. In original version there are another conditions (result set is much bigger)
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX purl: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://dbpedia.org/page/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT DISTINCT
?pageType
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
}
FILTER ( strstarts(str(?pageType), 'http://dbpedia.org/ontology') )
}
LIMIT 1000
sparql results
Here I select only page types to be clear with rest of the question.
This is the whole set. Now I want to exclude some pages. Exclude all agents (persons, organization etc):
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX purl: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://dbpedia.org/page/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT DISTINCT
?pageType
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent }
}
FILTER ( strstarts(str(?pageType), 'http://dbpedia.org/ontology') )
}
LIMIT 1000
The result.
Ok. Then I want to exclude more types, for example Written_Work. I tried different approaches, but unabled to find the correct one.
This returns nothing:
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent }
MINUS { ?page a dbo:WrittenWork }
}
This is like no filter is set:
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent, dbo:WrittenWork }
}
The question is:
what way should I go to exclude pages of certain types (direct and superclass)?
It look's like this is working answer (how to exclude multiple of types)
{
?page purl:subject ?id .
?page a ?pageType .
FILTER NOT EXISTS {
?page a/rdfs:subClassOf* ?skipClasses .
FILTER(?skipClasses in (dbo:Agent, dbo:Place, dbo:Work))
}
}
In this example all dbo:Agents, db:Places, dbo:Works will be filtered out.

SPARQL Wikidata - Retrieve members of Wikimedia Category

I want to retrieve the members of the Wikimedia Category American rock singers. I must use Wikidata and it tells me to use P31 with Q4167836 . The query below only returns information about the Category page and not about its members.
Is there any other way to retrieve the members of the Wikimedia Category? I also tried using the term dcterms:subject, which I use successfully with DBpedia, but in Wikidata the query returns empty results.
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
prefix wikibase: <http://wikiba.se/ontology#>
prefix bd: <http://www.bigdata.com/rdf#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?subject ?predicate ?object ?objectLabel WHERE {
?subject ?predicate ?object ; wdt:P31 wd:Q4167836 ;
rdfs:label "Category:American rock singers"#en
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" .}
}
Try here
Try this query on Wikidata:
SELECT ?subjectLabel WHERE {
?subject wdt:P27 wd:Q30;
wdt:P136 wd:Q11399 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" .}
}
Or try this query on DBpedia (as Mark Miller linked to):
SELECT str(?label) WHERE {
?subject dct:subject dbc:American_rock_singers ;
rdfs:label ?label .
FILTER (lang(?label) = "en")
}
Or if you must use Wikidata, try this federated query on Wikidata:
PREFIX dbc: <http://dbpedia.org/resource/Category:>
PREFIX dct: <http://purl.org/dc/terms/>
SELECT ?wsubjectLabel WHERE {
SERVICE <http://dbpedia.org/sparql> {
?subject dct:subject dbc:American_rock_singers .
?subject owl:sameAs ?wsubject .
FILTER (STRSTARTS(STR(?wsubject), "http://www.wikidata.org"))
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}

SPARQL BIND inside UNION is too slow

Given an IMDb ID, i want to get a list of directors and actors for that movie from Wikidata.
The problem is, I want to UNION both the director and actor query into a single column while also providing a new column with the role of director or actor.
Pretty easy query overall: first I get the movie entity from the IMDb ID, then I get all the directors from that movie followed by getting all the actors from that movie and UNION them together while filling a new column (?role) with the role.
This is what I have:
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
{ ?movie p:P57 ?cast .
?cast ps:P57 ?person .
BIND("director" as ?role) .
} UNION {
?movie p:P161 ?cast .
?cast ps:P161 ?person .
BIND("actor" as ?role) . }
?person wdt:P345 ?imdb .
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
This works and gives the result I want, problem is it takes about 10secs. If I remove the BINDs its instant speed, but I don't get a column with the roles.
I'd write this using values instead of bind and union. The idea is that you're saying when the properties are one thing, then ?role is one thing, and when the properties are another, ?role is another. The easy way to do that with values is something like:
select ?owner ?pet ?petType {
values (?hasPet ?petType) {
(:hasCat "cat")
(:hasDog "dog")
}
?owner ?hasPet ?pet
}
In your case, this would be:
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
values (?p ?ps ?role) {
(p:P161 ps:P161 "actor")
(p:P57 ps:P57 "director")
}
?movie ?p ?cast .
?cast ?ps ?person .
?person wdt:P345 ?imdb .
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
When I run this at query.wikidata.org, it produces 35 results almost instantly.
I guess that BIND leads to some problems with the query optimizer. You can try as an alternative to bind the role outside of the UNION clause, i.e.
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
?person wdt:P345 ?imdb .
{
?movie p:P57 ?c1 . ?c1 ps:P57 ?person .
?movie p:P57 ?cast .
} UNION {
?movie p:P161 ?c2 . ?c2 ps:P161 ?person .
?movie p:P161 ?cast .
}
BIND(IF(bound(?c1), "director", "actor") as ?role)
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
(If you do not the ?ref variable, you can omit the triple patterns to retrieve the ?cast in the UNION clauses.)