Sparql Skos: шире - PullRequest
       23

Sparql Skos: шире

4 голосов
/ 21 июля 2010

Я делаю SPARQL-запрос к DBpediaset, но у меня возникают некоторые проблемы (из-за отсутствия подробных знаний SPARQL) с ограничением запроса:

Сначала я получаю все музыкальные исполнители:1003 *

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

Но я хочу ограничить это более широкой категорией Category:American_musicians (через обход skos:broader?): Как?

* = пока вопрос конкретный, ясталкивался с этим квестом много раз, когда хотел выполнить запросы sparql.

Ответы [ 4 ]

5 голосов
/ 30 января 2013

Это можно упростить с помощью путей к свойствам в SPARQL 1.1

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

Здесь отображаются все предки, с которыми можно связаться через свойство skos:broader.

2 голосов
/ 25 января 2017

Я удивлен, что на этот простой вопрос не был дан правильный ответ в течение 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 голос
/ 21 июля 2010

Нет действительно хорошего способа сделать это, но вот подробный способ:

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 и прекратить добавлять уровни, когдасчет перестает расти.

0 голосов
/ 03 декабря 2012

Это действительно легко выполнить в neo4j. Альтернативой для выполнения вашей задачи в SPARQL может быть извлечение всего подграфа в «Category: 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);
   }
}

Надеюсь, это поможет, - Дан

...