Как получить метки свойств из Викиданных с помощью SPARQL - PullRequest
0 голосов
/ 07 июня 2019

Я использую SPARQLWrapper для отправки SPARQL-запросов в Wikidata.В данный момент я пытаюсь найти все свойства для объекта.Например.с помощью простого кортежа, такого как: wd:Q11663 ?a ?b. Это само по себе работает, но я пытаюсь найти удобочитаемые ярлыки для возвращаемых свойств и сущностей.

Хотя SERVICE wikibase:label работает с использованием графического интерфейса Wikidata, это неработать с SPARQLWrapper - который настаивает на возвращении идентичных значений для переменной и ее «метки».

Запрос к свойству rdfs:label работает для сущности (? b), но этот подход не работает со свойством(? a).

может показаться, что свойство возвращается в виде полного URI, например http://www.wikidata.org/prop/direct/P1536.С помощью графического интерфейса я могу успешно запросить wd:P1536 ?a ?b..Это работает с SPARQLWrapper, если я отправляю его как второй запрос - но не в первом запросе.

Вот мой код:

from SPARQLWrapper import SPARQLWrapper, JSON

sparql = SPARQLWrapper("http://query.wikidata.org/sparql")

sparql.setQuery("""
  SELECT ?a ?aLabel ?propLabel ?b ?bLabel
  WHERE
  {
    wd:Q11663 ?a ?b.

    # Doesn't work with SPARQLWrapper
    #SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
    #?prop wikibase:directClaim ?p

    # but this does (and is more portable)
    ?b rdfs:label ?bLabel. filter(lang(?bLabel) = "en").

    # doesn't work
    #?a rdfs:label ?aLabel. 

    # property code can be extracted successfully
    BIND(  strafter(str(?a), "prop/direct/") AS ?propLabel).
    #BIND( CONCAT("wd:", strafter(str(?a), "prop/direct/") ) AS ?propLabel).

    # No matches, even if I concat 'wd:' to ?propLabel
    ?propLabel rdfs:label ?aLabel
    # generic search for any properties also fails
    #?propLabel ?zz ?aLabel.
   }
 """)

# However, this returns a label for P1536 - which is one of wd:Q11663's properties
sparql.setQuery("""SELECT ?b WHERE
   {
      wd:P1536 rdfs:label ?b.
   }
""")

Так как я могу получить метки для свойствв одном запросе (который должен быть более эффективным)?

[в сторону: да, я немного груб и готов с EN-фильтром - часто отбрасываю его, если ничего не получаю обратно]

1 Ответ

1 голос
/ 08 июня 2019

У меня были проблемы с двумя подходами - и код выше содержит смесь обоих.Кроме того, SPARQLWrapper здесь не проблема.

Первый подход, использующий службу метки wikibase, должен выглядеть следующим образом:

SELECT ?a ?aLabel ?propLabel ?b ?bLabel
WHERE
{
  ?item rdfs:label "weather"@en.
  ?item ?a ?b.

  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } 
  ?prop wikibase:directClaim ?a .
}

Этот код также включает поиск по метке ('weather') к объекту запроса (?item).

СЕРВИС работал, но если нет определения rdfs:label, он просто возвращает объект.Графический интерфейс и SPARQLWrapper (в конечную точку SPARQL) просто возвращали результаты в другом порядке - поэтому выглядело так, как будто я вижу много «неудачных» выходных данных (т. Е. Объекты и метки с ошибками отображаются одинаково).

Это стало ясно, когда я начал добавлять ОПЦИОНАЛЬНОЕ предложение к подходу ниже.

Строка ?prop wikibase:directClaim ?a . оказалась довольно простой.Wikibase определяет directClaim для сопоставления свойств с сущностями.Это позволяет ему определять кортежи о свойствах (т. Е. Метку).Многие другие онтологии просто используют те же идентификаторы.

Мой второй (более общий подход) - это подход, который вы найдете во многих книгах и онлайн-учебниках.Проблема здесь в том, что в свойствах викибазы есть полный URL, и мне нужно было преобразовать их в сущность.Я пытался манипулировать строками, но это приводит к строковому литералу, а не к сущности.Решение состоит в том, чтобы снова использовать directClaim:

?prop wikibase:directClaim ?a .
?prop rdfs:label ?propLabel.  filter(lang(?propLabel) = "en").

Обратите внимание, что это возвращает результат, только если определено rdfs:label.Добавление OPTIONAL вернет результаты, даже если метка не определена.

...