简体   繁体   English

Sparql skos:更广泛

[英]Sparql skos:broader

I'm doing a SPARQL query on the DBpediaset, but I am having some issues (due to lack of detailed SPARQL knowledge) with a query limitation: 我正在对DBpediaset进行SPARQL查询,但是由于查询限制,我遇到了一些问题(由于缺乏详细的SPARQL知识):

I first 'get' all music artists: 我首先'得到'所有音乐艺术家:

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

But I want to limit this to the broader category Category:American_musicians (via traversing skos:broader ?): how? 但是我想把它限制在更广泛的类别Category:American_musicians (通过遍历skos:broader ?):怎么样?

*= while the question is specific, I've encountered this quest many times when wanting to running sparql queries. * =虽然问题是具体的,但我想在运行sparql查询时多次遇到此任务。

This can be made easier with property paths in SPARQL 1.1 使用SPARQL 1.1中的属性路径可以更轻松地实现这一点

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

Here it displays all the ancestors that could be reached via the skos:broader property. 在这里它显示了可以通过skos:broader到达的所有祖先skos:broader属性。

I'm amazed this simple question hasn't been answered correctly in 3 years, and how much uncertainty and doubt people spread. 我很惊讶这个简单的问题在3年内没有得到正确回答,以及人们传播了多少不确定性和怀疑。

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

  • corrected a few prefixes: dbo instead of the long dbpedia-owl , dbc instead of category . 更正了一些前缀: dbo而不是长dbpedia-owldbc而不是category These short prefixes are builtin to DBpedia 这些简短的前缀内置于DBpedia
  • corrected skos:subject (no such prop exists) to dct:subject 校正的skos:subject (没有这样的道具存在)到dct:subject
  • corrected the query with property paths, it was missing / 用属性路径更正了查询,它丢失/
  • skos:broader is not transitive, skos:broaderTransitive is. skos:broader的不是传递, skos:broaderTransitive是。 However, DBpedia doesn't have the latter (no transitive reasoning) 但是,DBpedia没有后者(没有传递推理)
  • replaced DISTINCT which is expensive with FILTER EXISTS which is much faster. FILTER EXISTS取代了DISTINCT很贵,速度要快得多。 The FILTER can stop at the first relevant sub-category it finds, while the original query first finds all such sub-cats per artist, then discards them ( DISTINCT ), sorts the artists in memory and removes duplicates. FILTER可以停在它找到的第一个相关子类别,而原始查询首先找到每个艺术家的所有这些子猫,然后丢弃它们( DISTINCT ),在内存中对艺术家进行排序并删除重复项。

There's no really good way to do this, but here's a verbose way: 没有什么好方法可以做到这一点,但这里有一个冗长的方式:

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

For figuring out how many levels you need, you can change SELECT DISTINCT to SELECT COUNT DISTINCT and stop adding levels when the count stops going up. 要确定需要多少级别,可以将SELECT DISTINCT更改为SELECT COUNT DISTINCT,并在计数停止时停止添加级别。

This is really easy to perform in neo4j. 这在neo4j中很容易执行。 An alternative to accomplish your task in SPARQL could be to extract all the subgraph under "Category:American_musicians" by iterating via code on subcategories. 在SPARQL中完成任务的另一种方法是通过迭代子类别上的代码来提取“Category:American_musicians”下的所有子图。

Eg. 例如。 pseudo code in java would be something like: java中的伪代码类似于:

String startCategory = "<http://dbpedia.org/resource/Category:American_musicians>";
iterateTraversalFunction(startCategory);

then the traversal function would be: 那么遍历函数将是:

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);
   }
}

Hope this helps, - Dan 希望这会有所帮助, - 丹

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM