Как вернуть одиночный foaf: name?

У меня есть следующая DBpedia SPARQL, в которой показаны философы, оказавшие влияние на философов. Однако он возвращает дубликаты, если у философа более одного foaf:name:

SELECT ?name ?influencedName
  WHERE {
  ?philosopher a dbpedia-owl:Philosopher ;
    dbpedia-owl:influenced ?influenced ;
    foaf:name ?name .
  ?influenced  a dbpedia-owl:Philosopher ;
    foaf:name ?influencedName .
}

результаты SPARQL

Как я могу вернуть одно имя, если есть несколько значений для ?name и ?includedName. Я был бы доволен первым или наименьшим количеством символов, которые нужно выбрать, какие оставить.

Вот еще один пример влияния Платона на Бертрана Рассела. Я бы хотел вернуть одну строку, но получаю четыре:

SELECT ?name ?influencedName
  WHERE {
  ?philosopher a dbpedia-owl:Philosopher ;
    dbpedia-owl:influenced ?influenced ;
    foaf:name ?name , "Plato"@en .
  ?influenced  a dbpedia-owl:Philosopher ;
    foaf:name ?influencedName, "Bertrand Arthur William Russell, 3rd Earl Russell"@en .
}

SPARQL results


person Michael West    schedule 16.06.2013    source источник


Ответы (2)


Запросы

Похоже, вам нужен запрос вроде:

SELECT ?philosopher ?pName ?influence (SAMPLE(?iName) as ?iName)
WHERE {
  # This subquery selects all the philosophers and
  # selects just one of their names . 
  {
    SELECT ?philosopher (SAMPLE(?pName) as ?pName) WHERE {
      ?philosopher a dbpedia-owl:Philosopher ;
                   foaf:name ?pName .
    }
    GROUP BY ?philosopher
  }

  # This main query selects the influence of the 
  # philosophers and select their names.  The GROUP
  # BY on the outer query puts all the
  # (?philosopher,?pName,?influence,?iName) tuples 
  # that have the same ?philosopher, ?pName, and 
  # influence together, and the (SAMPLE(?iName) as ?iName)
  # in the outer SELECT combines them all, choosing an 
  # arbitrary representative ?iName.
  ?influence dbpedia-owl:influenced ?philosopher ;
             a dbpedia-owl:Philosopher ;
             foaf:name ?iName .
}
GROUP BY ?philosopher ?pName ?influence

результатах SPARQL

Если вас интересуют только имена, и вы не заботитесь о выборе фактических ресурсов, вам не нужны ?philosopher и ?influence во внешних SELECT, и вы можете сделать это

SELECT ?pName (SAMPLE(?iName) as ?iName)
WHERE { …

результаты SPARQL

Вы также можете добавить ORDER BY в конце, чтобы немного упростить проверку результатов:

…
GROUP BY ?philosopher ?pName ?influence
ORDER BY ?pName

результаты SPARQL

Эти последние результаты включают для Платона следующие строки:

"Plato"@en  "Socrates"@en
"Plato"@en  "Parmenides"@en
"Plato"@en  "Zeno of Elea"@en
"Plato"@en  "Pythagoras"@en
"Plato"@en  "Gorgias"@en
"Plato"@en  "Protagoras"@en
"Plato"@en  "Heraclitus"@en

В написанном здесь запросе я использовал SAMPLE , чтобы произвольно выбрать одну из foaf:name философии, но есть и другие функции в совокупная алгебра, которую можно использовать для выбора значения. Min может быть вам интересен, если вы хотите «первое» значение по порядку.

Подзапросы, GROUP BY, SAMPLE, MIN и т. Д.

На самом деле это очень похоже на пример, приведенный для подзапросов в разделе 12. , Подзапросы спецификации SPARQL. В этом примере следующий запрос используется для выбора людей, которых знает Алиса, и для каждого из них выбирается только одно из имен людей:

PREFIX : <http://people.example/>
SELECT ?y ?minName
WHERE {
  :alice :knows ?y .
  {
    SELECT ?y (MIN(?name) AS ?minName)
    WHERE {
      ?y :name ?name .
    } GROUP BY ?y
  }
}

Это было несложно приспособить к проблеме философского влияния. Проблема философов началась с выбора всех философов и их имен, группировки по фактическим философским ресурсам и выбора репрезентативного имени для каждого философа по образцу. Внешний запрос делает то же самое, но вместо отбора философов он выбирает сущности, которые повлияли на каждого философа. Результаты группируются, и выбирается репрезентативное название влияния.

person Joshua Taylor    schedule 16.06.2013
comment
Спасибо за быстрый ответ. У меня возникли проблемы с запросом, текущая проблема в том, что ничего не возвращает. Мне пришлось изменить псевдоним, поскольку я получал ошибки с повторяющимися именами переменных. Сегодня мой 4-й день работы со Sparql, я не знал, что поддерживаются подзапросы. Я продолжу работу над запросом и доложу - person Michael West; 16.06.2013
comment
Моя проблема с возвратом данных заключалась в том, что я использовал неправильный ПРЕФИКС dbpedia-owl. Правильный: PREFIX dbpedia-owl: ‹dbpedia.org/ontology ›Теперь я понимаю, что должен вернуть одно и то же имя для одного и того же философа как для субъекта, так и для предиката, поэтому выборка не будет работать. Я выясню, как определить единственное настоящее имя философа, и посмотрю, смогу ли я его адаптировать. Я отметил это как ответ, поскольку он действительно отвечает на поставленный вопрос. - person Michael West; 16.06.2013
comment
Недостаточно места в комментариях для моих выводов, поэтому отвечу на мой вопрос - person Michael West; 16.06.2013

Я определил, как я хочу выбрать уникальное имя для философа, см. Ниже sparql, который возвращает одно имя для каждого философа.

Однако я не понимаю, зачем включать это в более крупный запрос, который возвращает имя как для философа, так и для философа, находящегося под влиянием, без запуска этого кода один раз для каждого философа, что было бы большим и громоздким запросом. Я считаю, что мой код будет более читабельным, если я запущу имена философов и запросы, на которые влияют отдельные запросы, и буду искать имена в коде, а не в sparql. Возможно, мне не хватает какой-то функции sparql, которая упростит эту задачу. Пожалуйста посоветуй

Вот описание того, как я получаю уникальные имена:

Получите все имена для философа из foaf: names и dbprop: names. Фильтр для включения только имен, содержащих хотя бы один символ латинской буквы (A-Z). Найдите длину самых коротких имен. Выберите минимум из всех самых коротких имен.

PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbpprop: <http://dbpedia.org/property/>

SELECT ?philosopher (min(?name) as ?minName)
WHERE {{
   ?philosopher foaf:name ?name        .
  } UNION {
   ?philosopher dbpprop:name ?name     .
  }
  FILTER( strlen(?name) = ?minLength )   .  # get the shortest names
  FILTER( REGEX( str(?name) , "[A-Z]" )) .  # exlude names with no latin charachters
  {
    SELECT ?philosopher (min(strlen(?name)) as ?minLength)
    WHERE {{
      ?philosopher a  dbpedia-owl:Philosopher ;
         foaf:name ?name .
    } UNION {
      ?philosopher a  dbpedia-owl:Philosopher ;
         dbpprop:name ?name .
    }
    FILTER( REGEX( str(?name) , "[A-Z]" )) .
    }
    GROUP BY ?philosopher
  }
}
GROUP BY ?philosopher
ORDER BY ?philosopher
person Michael West    schedule 16.06.2013