我正在对DBpediaset进行SPARQL查询,但由于查询限制,我遇到了一些问题(由于缺乏详细的SPARQL知识):
我首先'得到'所有音乐艺术家:
?person rdf:type <http://dbpedia.org/ontology/MusicalArtist> .
但我想将此限制在更广泛的类别Category:American_musicians
(通过遍历skos:broader
?):如何?
* =虽然问题是具体的,但我想在运行sparql查询时多次遇到此任务。
答案 0 :(得分:4)
使用SPARQL 1.1中的属性路径可以使这更容易。
SELECT DISTINCT ( ?person )
WHERE
{
?person rdf:type dbpedia-owl:MusicalArtist .
?person skos:subject skos:broader* category:American_musicians .
}
此处显示可通过skos:broader
属性访问的所有祖先。
答案 1 :(得分:1)
没有什么好方法可以做到这一点,但这里有一个冗长的方式:
SELECT DISTINCT ( ?person )
WHERE
{
?person rdf:type dbpedia-owl:MusicalArtist .
{
?person skos:subject [ skos:broader category:American_musicians ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader category:American_musicians ] ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader [ skos:broader category:American_musicians ] ] ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader [ skos:broader [ skos:broader category:American_musicians ] ] ] ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader category:American_musicians ] ] ] ] ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader category:American_musicians ] ] ] ] ] ] .
} UNION {
?person skos:subject [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader [ skos:broader category:American_musicians ] ] ] ] ] ] ] .
}
}
要确定需要多少级别,可以将SELECT DISTINCT更改为SELECT COUNT DISTINCT,并在计数停止时停止添加级别。
答案 2 :(得分:1)
我很惊讶这个简单的问题在3年内没有得到正确回答,以及人们传播了多少不确定性和怀疑。
SELECT * {
?person a dbo:MusicalArtist .
filter exists {?person dct:subject/skos:broader* dbc:American_musicians}
}
dbo
而不是长dbpedia-owl
,dbc
而不是category
。这些简短的前缀内置于DBpedia skos:subject
(不存在此类道具)至dct:subject
/
skos:broader
不具有传递性,skos:broaderTransitive
是。但是,DBpedia没有后者(没有传递性推理)DISTINCT
FILTER EXISTS
,FILTER
费用更高。 DISTINCT
可以停在它找到的第一个相关子类别,而原始查询首先找到每个艺术家的所有这些子猫,然后丢弃它们({{1}}),在内存中对艺术家进行排序并删除重复。答案 3 :(得分:0)
这在neo4j中很容易执行。在SPARQL中完成任务的另一种方法是通过迭代子类别上的代码来提取“Category:American_musicians”下的所有子图。
EG。 java中的伪代码类似于:
String startCategory = "<http://dbpedia.org/resource/Category:American_musicians>";
iterateTraversalFunction(startCategory);
那么遍历函数将是:
public void iterateTraversalFunction(String startCategory){
ArrayList<String> artistsURI = // SPARQL query ?person skos:subject startCategory . ?person rdf:type MusicalArtist
ArrayList<String> subCategoriesURI = // SPARQL query ?subCat skos startCategory
// Repeat recursively
for(String subCatURI: subCategoriesURI){
iterateTraversalFunction(subCatURI);
}
}
希望这有帮助, - 丹