zadrozny
zadrozny

Reputation: 1731

Getting all the children of a Wikidata item (but not instances)

For example, take these three cases:

Triangle Shirtwaist Factory fire (Q867316) : instance of (P31): disaster (Q3839081)
disaster:  subclass of (P279) :  occurrence (Q1190554) 
occurrence (Q1190554) : subclass of:  temporal entity (Q26907166) 

World's Fair (Q172754) : subclass of (P279) :  exhibition (Q464980) 
exhibition (Q464980)  : subclass of (P279) :  event (Q1656682) 
event (Q1656682) : subclass of (P279) : occurrence (Q1190554)
occurrence (Q1190554) : subclass of:  temporal entity (Q26907166) 

Peloponnesian War (Q33745) :  instance of (P31):  war (Q198) 
war (Q198) : subclass of (P279) : occurrence (Q1190554)
occurrence (Q1190554) : subclass of:  temporal entity (Q26907166)

I would like all the descendants of temporal entity stopping before the instances (Triangle Shirtwaist Factory fire, World's Fair, Peloponnesian War).

Is there a way to do this with SPARQL or the API?

Upvotes: 1

Views: 1034

Answers (1)

tobias47n9e
tobias47n9e

Reputation: 2231

If I understand you correctly you just want to get the way instances are classified on Wikidata.

So starting with the example @AKSW gave:

SELECT DISTINCT ?event_type ?event_typeLabel { 
    ?event_type wdt:P279* wd:Q26907166 
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 100

The * is a pretty expensive operation to calculate and by the time of writing Wikidata has close to 50 million items. That is why I had to add the LIMIT because I was getting time-outs without it.

Graphing it

To get a feel for the data I like to look at it in the Wikidata graph builder. Because it shows clustering so nice.

https://angryloki.github.io/wikidata-graph-builder/?property=P279&item=Q26907166&iterations=2&mode=reverse

enter image description here

As you can see there are already a lot of classifications after 2 iterations. So we might also already be happy with this query:

SELECT DISTINCT ?event_type ?event_typeLabel { 
    ?event_type wdt:P279/wdt:P279 wd:Q26907166 
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

Note that it only goes 2 times along the property P279. At the moment this gives me 281 items.

If you really need to traverse the tree in full you can filter out "instance of" (P31) statements using FILTER NOT EXISTS. But the problem is that that currently always runs into timeouts:

SELECT DISTINCT ?event_type ?event_typeLabel { 
    ?event_type wdt:P279* wd:Q26907166 .
    FILTER NOT EXISTS { ?event_type wdt:P31 [] }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 100

With a subquery you can limit the results from the tree, but you will get incomplete data:

SELECT ?event_type ?event_typeLabel
WHERE
{
    {
      SELECT DISTINCT ?event_type
      WHERE                
      { 
        ?event_type wdt:P279* wd:Q26907166 .
      }
      LIMIT 1000
    }

    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } 
    FILTER NOT EXISTS { ?event_type wdt:P31 [] }   
}

Upvotes: 3

Related Questions