Sparql 获取Wikidata项的所有子项(但不获取实例)

Sparql 获取Wikidata项的所有子项(但不获取实例),sparql,wikidata,wikidata-api,Sparql,Wikidata,Wikidata Api,例如,以这三种情况为例: 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) : subc

例如,以这三种情况为例:

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)
我希望
时间实体
的所有后代在实例之前停止(
三角衬衫工厂火灾
世界博览会
伯罗奔尼撒战争


有没有办法用SPARQL或API做到这一点?

如果我理解正确,您只想了解在Wikidata上对实例进行分类的方式

因此,从@AKSW给出的示例开始:

SELECT DISTINCT ?event_type ?event_typeLabel { 
    ?event_type wdt:P279* wd:Q26907166 
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 100
*
是一个非常昂贵的计算操作,到编写Wikidata时,它已经有近5000万个条目。这就是为什么我必须添加
限制
,因为没有它我会超时

作图 为了了解数据,我喜欢在Wikidata graph builder中查看它。因为它显示了集群非常好

正如您所看到的,经过2次迭代之后,已经有很多分类了。因此,我们可能已经对这个查询感到满意:

SELECT DISTINCT ?event_type ?event_typeLabel { 
    ?event_type wdt:P279/wdt:P279 wd:Q26907166 
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
请注意,它仅沿属性P279移动2次。目前,这给了我281个项目

如果确实需要完整遍历树,可以使用
filter NOT EXISTS
过滤掉“instance of”(P31)语句。但问题是,目前该系统总是会超时:

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
通过子查询,您可以限制来自树的结果,但会得到不完整的数据:

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

是的,有可能。这只是最简单的查询之一,通过传递方式查询所有子类…如果您在下次之前尝试一些东西,这将是很好的…
选择DISTINCT?s{s wdt:P279*wd:Q26907166}
如果没有
*
,您将只得到直接的子类。