4

我正在对 DBpediaset 进行 SPARQL 查询,但我遇到了一些问题(由于缺乏详细的 SPARQL 知识)和查询限制:

我首先“获取”所有音乐艺术家:

?person rdf:type <http://dbpedia.org/ontology/MusicalArtist> .

但我想将其限制为更广泛的类别Category:American_musicians(通过遍历skos:broader?):如何?

*= 虽然问题很具体,但我在想要运行 sparql 查询时多次遇到过这个问题。

4

4 回答 4

5

这可以通过 SPARQL 1.1 中的属性路径变得更容易

SELECT DISTINCT ( ?person )
WHERE
{
  ?person rdf:type dbpedia-owl:MusicalArtist .
  ?person skos:subject  skos:broader* category:American_musicians  .
}

在这里,它显示了可以通过该skos:broader属性到达的所有祖先。

于 2013-01-30T02:31:50.480 回答
2

我很惊讶这个简单的问题在 3 年内没有得到正确回答,以及人们传播了多少不确定性和怀疑。

SELECT * { ?person a dbo:MusicalArtist . filter exists {?person dct:subject/skos:broader* dbc:American_musicians} }

  • 更正了一些前缀:dbo而不是 long dbpedia-owldbc而不是category. 这些短前缀内置于 DBpedia
  • 更正skos:subject(不存在这样的道具)为dct:subject
  • 用属性路径更正了查询,它丢失了/
  • skos:broader不及物,skos:broaderTransitive是。但是,DBpedia 没有后者(没有传递推理)
  • 替换DISTINCT哪个昂贵,FILTER EXISTS哪个更快。可以在它找到的FILTER第一个相关子类别处停止,而原始查询首先找到每个艺术家的所有此类子猫,然后丢弃它们(DISTINCT),对内存中的艺术家进行排序并删除重复项。
于 2017-01-25T07:25:53.050 回答
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 并在计数停止上升时停止添加级别。

于 2010-07-21T15:49:13.810 回答
0

这在 neo4j 中非常容易执行。在 SPARQL 中完成任务的另一种方法是通过子类别上的代码迭代来提取“类别:American_musicians”下的所有子图。

例如。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);
   }
}

希望这会有所帮助, - 丹

于 2012-12-02T20:40:35.277 回答