SPARQL на примерах Wikidata: различия между версиями

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
(спрятал от читателей разбивку по количеству объектов (неточная и будет устаревать))
Нет описания правки
 
(не показано 12 промежуточных версий 2 участников)
Строка 1: Строка 1:
{{Статья|Черновик|SPARQL-with-Wikidata}}
{{Статья|Опубликована|sparql_wikidata}}


{{Аннотация|SPARQL — это язык запросов к данным, основанных на модели "субъект-предикат-значение" (в терминах Wikidata элемент-[https://www.wikidata.org/wiki/Help:Statements/ru свойство-значения], item-property-values). Wikidata - это открытый проект, потенциально интересный в гео-проектах и доступный в виде публичной SPARQL-точки}}
{{Аннотация|SPARQL — это язык запросов к данным, основанных на модели "субъект-предикат-объект" (примечание: "объект" часто заменяется на "значение", особенно в случае количественных предикатов) (в терминах Wikidata элемент-[https://www.wikidata.org/wiki/Help:Statements/ru свойство-значения], item-property-values). Wikidata открытый проект, потенциально интересный в гео-проектах и доступный в виде публичной SPARQL-точки}}


== Инструментарий запросов ==
== Инструментарий запросов ==
Строка 8: Строка 8:
=== query.wikidata.org ===
=== query.wikidata.org ===


У этого сервиса есть целое руководство на английском языке https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual и репозиторий для разработчиков https://github.com/wikimedia/wikidata-query-rdf.
У сервиса query.wikidata.org есть целое руководство на английском языке https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual и репозиторий для разработчиков https://github.com/wikimedia/wikidata-query-rdf.


Обратите внимание, что результаты запросов можно скачать в формате CSV — хорошее подспорье для более серьёзной работы с помощью других инструментов.
Обратите внимание, что результаты запросов можно скачать в формате CSV — хорошее подспорье для более серьёзной работы при помощи других инструментов.


В таблице результатов (в нижней части экрана) можно отфильтровать результаты, используя поиск по всем полям сразу (например, можно попробовать найти "Moscow").
В таблице результатов (в нижней части экрана) можно отфильтровать результаты, используя поиск по всем полям сразу (например, можно попробовать найти "Moscow").
Строка 16: Строка 16:
== Wikidata ==
== Wikidata ==


Для помощи по терминологии и модели Wikidata можно посмотреть сюда: https://www.wikidata.org/wiki/Wikidata:Glossary/ru Викиданные:Глоссарий]
Для помощи по терминологии и модели Wikidata можно посмотреть сюда: [https://www.wikidata.org/wiki/Wikidata:Glossary/ru Викиданные:Глоссарий].
 
Структуру ''элемента'' (item) и ''свойства'' (property) можно найти на англоязычной странице [https://www.mediawiki.org/wiki/Wikibase/DataModel/Primer Wikibase/DataModel/Primer].
 
* ''Множественные значения''
* ''Отсутствующие значения'' (известно, что значения не может быть) эквивалентны тегам ключ=no из OpenStreetMap - описаны на странице ''[https://www.wikidata.org/wiki/Help:Statements/ru Help:Утверждения]''
* ''Значение не определено'' (известно, что значение есть, но не известно какое) - описаны на той же странице


[https://commons.wikimedia.org/wiki/File:Wikidata_statement_ru.svg Диаграмма русскоязычной терминологии утверждений в Викиданных]
[https://commons.wikimedia.org/wiki/File:Wikidata_statement_ru.svg Диаграмма русскоязычной терминологии утверждений в Викиданных]
Строка 23: Строка 29:
Полный перечень свойств: [https://www.wikidata.org/wiki/Wikidata:List_of_properties Wikidata:List_of_properties]
Полный перечень свойств: [https://www.wikidata.org/wiki/Wikidata:List_of_properties Wikidata:List_of_properties]


Отчёт количества объектов по каждому свойству - [https://www.wikidata.org/wiki/Wikidata:Database_reports/List_of_properties/all Wikidata:Database_reports/List_of_properties/all]
Отчёт количества использований каждого свойства - [https://www.wikidata.org/wiki/Wikidata:Database_reports/List_of_properties/all Wikidata:Database_reports/List_of_properties/all]


* дата прекращения существования - https://www.wikidata.org/wiki/Property:P576
* дата прекращения существования - https://www.wikidata.org/wiki/Property:P576
Строка 63: Строка 69:
* город - https://www.wikidata.org/wiki/Q515
* город - https://www.wikidata.org/wiki/Q515


* северный полюс - https://www.wikidata.org/wiki/Q934
* Северный полюс - https://www.wikidata.org/wiki/Q934
* южный полюс - https://www.wikidata.org/wiki/Q933
* Южный полюс - https://www.wikidata.org/wiki/Q933


* гора - https://www.wikidata.org/wiki/Q8502
* гора - https://www.wikidata.org/wiki/Q8502
Строка 70: Строка 76:
== Wikidata Blazegraph ==
== Wikidata Blazegraph ==


blazegraph - расширения от Wikidata к [https://www.blazegraph.com/ Blazegraph] чтобы сделать запросы к Wikibase более эффективными. Лицензия GPLv2.
Blazegraph — расширение от Wikidata к [https://www.blazegraph.com/ Blazegraph], чтобы сделать запросы к Wikibase более эффективными. Имеет лицензию GPLv2.


* функция [https://github.com/wikimedia/wikidata-query-rdf/blob/master/blazegraph/src/main/java/org/wikidata/query/rdf/blazegraph/constraints/WikibaseDistanceBOp.java geof:distance] возвращает минимальное расстояние между двумя точками.
* Функция [https://github.com/wikimedia/wikidata-query-rdf/blob/master/blazegraph/src/main/java/org/wikidata/query/rdf/blazegraph/constraints/WikibaseDistanceBOp.java geof:distance] возвращает минимальное расстояние между двумя точками.


== Элементы SPARQL запросов ==
== Элементы SPARQL-запросов ==
Т.к. исходные данные представляют граф (элемент-свойство-значения) и его расширения (в Wikidata: квалификаторы, ссылки и др.), то большинство запросов SPARQL строятся вокруг поиска ''паттернов в графе''<ref>https://www.w3.org/TR/sparql11-query/#GraphPattern</ref>, зачастую нескольких.
Т.к. исходные данные представляют граф (элемент-свойство-значения) и его модификации (в Wikidata: квалификаторы, ссылки и др.), то большинство SPARQL-запросов строятся вокруг поиска ''паттернов в графе''<ref>https://www.w3.org/TR/sparql11-query/#GraphPattern</ref>, зачастую нескольких.


=== Города в России с телефонными кодами ===
=== Города в России с телефонными кодами ===
Строка 81: Строка 87:
Самый простой пример.
Самый простой пример.
* 1 строка: SELECT запросы<ref>https://www.w3.org/TR/sparql11-query/#QueryForms</ref> выбирают данные или их часть
* 1 строка: SELECT запросы<ref>https://www.w3.org/TR/sparql11-query/#QueryForms</ref> выбирают данные или их часть
* 2 строка: выбираем субъекты (?item) у которых явно указано, что они в стране - ''Россия'' (Q159)
* 2 строка: выбираем субъекты (?item), у которых явно указано, что они в стране - ''Россия'' (Q159)
* 3 строка: выбираем субъекты (?item) у которых явно указано, что они суть - ''города'' (Q515)
* 3 строка: выбираем субъекты (?item), у которых явно указано, что они суть - ''города'' (Q515)
* 4-6 строка: т.к. значения предиката "ID отношения из OpenStreetMap" P402 могут быть просто не заполнены у отдельных объектов, такие объекты будут исключены из результатов. Это не совсем интуитивно понятно для людей, привыкших к SQL-запросам (где NULL-значения возвращаются в большинстве случаев). В SPARQL ''необязательные значения''<ref>https://www.w3.org/TR/sparql11-query/#optionals</ref> нужно включать в результаты вручную.
* 4-6 строка: т.к. значения предиката "ID отношения из OpenStreetMap" P402 могут быть просто не заполнены у отдельных объектов, такие объекты будут исключены из результатов. Это не совсем интуитивно понятно для людей, привыкших к SQL-запросам (где NULL-значения возвращаются в большинстве случаев). В SPARQL ''необязательные значения''<ref>https://www.w3.org/TR/sparql11-query/#optionals</ref> нужно включать в результаты вручную.
* 7 строка: выбираем все возможные субъекты и объекты у предиката P473 (код города). Примечание о части "?localdialingcode": в Wikidata у [https://www.wikidata.org/wiki/Q649 Москвы] указано сразу два объекта "495" и "499" у предиката P473, поэтому вернутся 2 результата, а не один. В SQL пришлось бы писать JOIN на ровном месте, а в SPARQL его нет вообще.
* 7 строка: выбираем все возможные субъекты и объекты у предиката P473 (код города). Примечание о части "?localdialingcode": в Wikidata у [https://www.wikidata.org/wiki/Q649 Москвы] указано сразу два объекта "495" и "499" у предиката P473, поэтому вернутся 2 результата, а не один. В SQL пришлось бы писать JOIN на ровном месте, а в SPARQL его нет вообще.
Строка 107: Строка 113:
Более того, в отличие от реляционных подходов, мы избавлены от вопросов: "в какой именно таблице хранятся города", "в какой таблице хранится информация о побратимстве". Сложность отличий нормальных форм не сбрасывается сразу на пользователя на уровне языка запросов. Необходимость в тщательном дизайне баз данных (таблиц и отношений) тоже уменьшается (по сравнению с табличным подходом и SQL).
Более того, в отличие от реляционных подходов, мы избавлены от вопросов: "в какой именно таблице хранятся города", "в какой таблице хранится информация о побратимстве". Сложность отличий нормальных форм не сбрасывается сразу на пользователя на уровне языка запросов. Необходимость в тщательном дизайне баз данных (таблиц и отношений) тоже уменьшается (по сравнению с табличным подходом и SQL).


Составители запросов SPARQL просто исследуют данные запросами, а не постоянно думают где именно эти данные расположены и как именно их будут связывать.
Составители SPARQL-запросов просто исследуют данные запросами, а не думают постоянно, где именно эти данные расположены и как именно они связаны между собой.


* Строка 2: [https://www.wikidata.org/wiki/Q2366010 Академический район] будет выбран как находящийся в России.
* Строка 2: [https://www.wikidata.org/wiki/Q2366010 Академический район] будет выбран как находящийся в России.
* Строка 4: [https://www.wikidata.org/wiki/Q33349 Мелитополь] (Украина) будет выбран как побратим Академического района.
* Строка 4: [https://www.wikidata.org/wiki/Q33349 Мелитополь] (Украина) будет выбран как побратим Академического района.
* Строка 7: исключаем исторические страны у городов-побратимов в результатах
* Строка 7: Исключаем исторические страны у городов-побратимов в результатах


[https://query.wikidata.org/#SELECT%20DISTINCT%20%3FwikidataCity%20%3FrussianPlace%20%3Fcountry%20WHERE%20%7B%0A%20%20%3FrussianPlace%20wdt%3AP17%20wd%3AQ159%20.%0A%20%20%0A%20%20%3FrussianPlace%20wdt%3AP190%20%3FwikidataCity%20.%0A%20%20%3FwikidataCity%20wdt%3AP17%20%3Fcountry%20.%0A%20%20%0A%20%20FILTER%20NOT%20EXISTS%20%7B%3Fcountry%20wdt%3AP31%20wd%3AQ3024240%7D%0A%7D%0AORDER%20BY%20%3FrussianPlace%20%3Fcountry Открыть на query.wikidata.org]
[https://query.wikidata.org/#SELECT%20DISTINCT%20%3FwikidataCity%20%3FrussianPlace%20%3Fcountry%20WHERE%20%7B%0A%20%20%3FrussianPlace%20wdt%3AP17%20wd%3AQ159%20.%0A%20%20%0A%20%20%3FrussianPlace%20wdt%3AP190%20%3FwikidataCity%20.%0A%20%20%3FwikidataCity%20wdt%3AP17%20%3Fcountry%20.%0A%20%20%0A%20%20FILTER%20NOT%20EXISTS%20%7B%3Fcountry%20wdt%3AP31%20wd%3AQ3024240%7D%0A%7D%0AORDER%20BY%20%3FrussianPlace%20%3Fcountry Открыть на query.wikidata.org]
Строка 129: Строка 135:
В отличие от OpenStreetMap, Wikidata не ограничен "существующими прямо сейчас" объектами. Это можно использовать как хороший пример исключения из результатов.
В отличие от OpenStreetMap, Wikidata не ограничен "существующими прямо сейчас" объектами. Это можно использовать как хороший пример исключения из результатов.
* 5 строка: исключаем<ref>https://www.w3.org/TR/sparql11-query/#negation</ref> те страны, которые - исторические
* 5 строка: исключаем<ref>https://www.w3.org/TR/sparql11-query/#negation</ref> те страны, которые - исторические
* 10 строка: результаты упорядочены<ref>https://www.w3.org/TR/sparql11-query/#solutionModifiers</ref> по названиям на русском или английском
* 10 строка: результаты упорядочены<ref>https://www.w3.org/TR/sparql11-query/#solutionModifiers</ref> по названиям на русском или английском языках.


[https://query.wikidata.org/#SELECT%20DISTINCT%20%3Fcountry%20%3FcountryLabel%20%3Fcapital%20%3FcapitalLabel%0AWHERE%0A%7B%0A%20%20%3Fcountry%20wdt%3AP31%20wd%3AQ3624078%20.%0A%20%20FILTER%20NOT%20EXISTS%20%7B%3Fcountry%20wdt%3AP31%20wd%3AQ3024240%7D%0A%20%20OPTIONAL%20%7B%20%3Fcountry%20wdt%3AP36%20%3Fcapital%20%7D%20.%0A%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%22%2C%20%22en%22%20%7D%0A%7D%0AORDER%20BY%20%3FcountryLabel Открыть на query.wikidata.org]
[https://query.wikidata.org/#SELECT%20DISTINCT%20%3Fcountry%20%3FcountryLabel%20%3Fcapital%20%3FcapitalLabel%0AWHERE%0A%7B%0A%20%20%3Fcountry%20wdt%3AP31%20wd%3AQ3624078%20.%0A%20%20FILTER%20NOT%20EXISTS%20%7B%3Fcountry%20wdt%3AP31%20wd%3AQ3024240%7D%0A%20%20OPTIONAL%20%7B%20%3Fcountry%20wdt%3AP36%20%3Fcapital%20%7D%20.%0A%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%22%2C%20%22en%22%20%7D%0A%7D%0AORDER%20BY%20%3FcountryLabel Открыть на query.wikidata.org]
Строка 145: Строка 151:
</syntaxhighlight>
</syntaxhighlight>


=== Города примерно с таким же населением как и Пермь ===
=== Города примерно с таким же населением, как Пермь ===
Города, отличающиеся менее чем на 1000 населения от [https://www.wikidata.org/wiki/Q915 Перми].
Города, отличающиеся от [https://www.wikidata.org/wiki/Q915 Перми] менее чем на 1000 человек по численности населения.


* 6 строка: abs<ref>https://www.w3.org/TR/sparql11-query/#func-abs</ref> это одна из множества возможных ''функций на числах'' в ''тестовых выражениях'' и ''фильтрах''<ref>https://www.w3.org/TR/sparql11-query/#expressions</ref>  
* 6 строка: abs<ref>https://www.w3.org/TR/sparql11-query/#func-abs</ref> это одна из множества возможных ''функций на числах'' в ''тестовых выражениях'' и ''фильтрах''<ref>https://www.w3.org/TR/sparql11-query/#expressions</ref>  
Строка 164: Строка 170:
=== Ранжирование городов по населению ===
=== Ранжирование городов по населению ===


* Строка 10-17: BIND конструкция<ref>https://www.w3.org/TR/sparql11-query/#assignment</ref> позволяет создать переменную и присвоить ей значение. В данном примере мы использовали другую переменную (?population) чтобы создать новую (?layer)
* Строка 10-17: BIND-конструкция<ref>https://www.w3.org/TR/sparql11-query/#assignment</ref> позволяет создать переменную и присвоить ей значение. В данном примере мы использовали другую переменную (?population), чтобы создать новую (?layer)
* Строка 11: первый из 5 вложенных в "хвостовую часть" IF(условие, значение при истине, значение при не истине)
* Строка 11: первый из 5 вложенных в "хвостовую часть" IF (условие, значение при истине, значение при не истине)


[https://query.wikidata.org/#%23defaultView%3AMap%0ASELECT%20DISTINCT%20%3Fcity%20%3FcityLabel%20%3Fpopulation%20%3Flayer%20%3Fcoordinates%20WHERE%20%7B%0A%20%20%3Fcity%20wdt%3AP17%20wd%3AQ159.%0A%20%20%3Fcity%20wdt%3AP31%20wd%3AQ515.%0A%0A%20%20OPTIONAL%20%7B%20%3Fcity%20wdt%3AP1082%20%3Fpopulation.%20%7D%0A%20%20%0A%20%20%3Fcity%20wdt%3AP625%20%3Fcoordinates.%0A%20%20%0A%20%20BIND%28%0A%20%20%20%20IF%28%3Fpopulation%20%3C%20500%2C%20%22500%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%2010000%2C%20%2210K%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%20100000%2C%20%22100K%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%201000000%2C%20%221M%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%2010000000%2C%20%2210M%22%2C%0A%20%20%20%20%22%3E20M%22%29%29%29%29%29%0A%20%20%20%20AS%20%3Flayer%29.%0A%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%2Cen%22%20%7D%0A%7D%0AORDER%20BY%20%0ADESC%28%3Fpopulation%29 Открыть на query.wikidata.org]
[https://query.wikidata.org/#%23defaultView%3AMap%0ASELECT%20DISTINCT%20%3Fcity%20%3FcityLabel%20%3Fpopulation%20%3Flayer%20%3Fcoordinates%20WHERE%20%7B%0A%20%20%3Fcity%20wdt%3AP17%20wd%3AQ159.%0A%20%20%3Fcity%20wdt%3AP31%20wd%3AQ515.%0A%0A%20%20OPTIONAL%20%7B%20%3Fcity%20wdt%3AP1082%20%3Fpopulation.%20%7D%0A%20%20%0A%20%20%3Fcity%20wdt%3AP625%20%3Fcoordinates.%0A%20%20%0A%20%20BIND%28%0A%20%20%20%20IF%28%3Fpopulation%20%3C%20500%2C%20%22500%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%2010000%2C%20%2210K%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%20100000%2C%20%22100K%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%201000000%2C%20%221M%22%2C%0A%20%20%20%20IF%28%3Fpopulation%20%3C%2010000000%2C%20%2210M%22%2C%0A%20%20%20%20%22%3E20M%22%29%29%29%29%29%0A%20%20%20%20AS%20%3Flayer%29.%0A%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%2Cen%22%20%7D%0A%7D%0AORDER%20BY%20%0ADESC%28%3Fpopulation%29 Открыть на query.wikidata.org]
Строка 218: Строка 224:
</syntaxhighlight>
</syntaxhighlight>


=== Города, которые соединяются с Транссибирской магистралью или Трансмонгольской железной дорогой ===
=== Города, которые соединяются Транссибирской магистралью или Трансмонгольской железной дорогой ===


* 5 строка: конструкция VALUES<ref>https://www.w3.org/TR/sparql11-query/#inline-data</ref> используется чтобы вручную указать значения у отдельных элементов<ref>http://www.snee.com/bobdc.blog/2012/09/sparql-11s-new-values-keyword.html</ref>
* 5 строка: конструкция VALUES<ref>https://www.w3.org/TR/sparql11-query/#inline-data</ref> используется чтобы вручную указать значения у отдельных элементов


[https://query.wikidata.org/#%23defaultView%3AMap%0ASELECT%20%3Fcity%20%3FcityLabel%20%3Fcoordinates%0AWHERE%0A%7B%0A%20%20%20VALUES%20%3Fhighway%20%7B%20wd%3AQ559037%20wd%3AQ58767%20%7D%20%0A%20%20%20%3Fhighway%20wdt%3AP2789%20%3Fcity%20.%0A%20%20%20%20%3Fcity%20wdt%3AP625%20%3Fcoordinates%20.%0A%20%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%2Cen%22.%20%7D%0A%7D Открыть на query.wikidata.org]
[https://query.wikidata.org/#%23defaultView%3AMap%0ASELECT%20%3Fcity%20%3FcityLabel%20%3Fcoordinates%0AWHERE%0A%7B%0A%20%20%20VALUES%20%3Fhighway%20%7B%20wd%3AQ559037%20wd%3AQ58767%20%7D%20%0A%20%20%20%3Fhighway%20wdt%3AP2789%20%3Fcity%20.%0A%20%20%20%20%3Fcity%20wdt%3AP625%20%3Fcoordinates%20.%0A%20%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%2Cen%22.%20%7D%0A%7D Открыть на query.wikidata.org]
Строка 236: Строка 242:
</syntaxhighlight>
</syntaxhighlight>


== Wikidata префиксы ==
== Wikidata-префиксы ==
[https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format#Full_list_of_prefixes Полный список префиксов].
[https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format#Full_list_of_prefixes Полный список префиксов].


=== Квалификаторы (qualifier) ===
=== Квалификаторы (qualifier) ===


Если открыть [https://www.wikidata.org/wiki/Q915 Пермь], то там указанно множество значений у численности населения (P1082), причём все значения - одного ранга (нормальный).
Если открыть [https://www.wikidata.org/wiki/Q915 Пермь], то там указанно множество значений у численности населения (P1082), причём все значения одного ранга (нормальный).


У некоторых из значений численности населения указаны [https://www.wikidata.org/wiki/Help:Qualifiers/ru квалификаторы] (qualifier) P585 (момент времени) и P459 (метод определения).  
У некоторых из значений численности населения указаны [https://www.wikidata.org/wiki/Help:Qualifiers/ru квалификаторы] (qualifier) P585 (момент времени) и P459 (метод определения).  
Строка 247: Строка 253:
* 2 строка: будут выбраны все 43 высказывания у элемента Q915 и свойства P1082
* 2 строка: будут выбраны все 43 высказывания у элемента Q915 и свойства P1082
* 3 строка: выбираем их значения
* 3 строка: выбираем их значения
* 4-5 строка: выбираем нужные квалификаторы
* 4-5 строка: выбираем нужные квалификаторы.


[https://query.wikidata.org/#SELECT%20%3Fvalue%20%3Fqualifier%20%3Fwikidataid%20WHERE%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wd%3AQ915%20p%3AP1082%20%3Fstatements%20%20%20%20%20%20%20%20%20%20%20.%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Fstatements%20ps%3AP1082%20%3Fvalue%20%20%20%20%20%20.%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Fstatements%20pq%3AP585%20%20%3Fqualifier%20%20.%0A%20OPTIONAL%20%7B%20%3Fstatements%20pq%3AP459%20%20%3Fwikidataid%20.%20%7D%0A%7D Открыть на query.wikidata.org]
[https://query.wikidata.org/#SELECT%20%3Fvalue%20%3Fqualifier%20%3Fwikidataid%20WHERE%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wd%3AQ915%20p%3AP1082%20%3Fstatements%20%20%20%20%20%20%20%20%20%20%20.%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Fstatements%20ps%3AP1082%20%3Fvalue%20%20%20%20%20%20.%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Fstatements%20pq%3AP585%20%20%3Fqualifier%20%20.%0A%20OPTIONAL%20%7B%20%3Fstatements%20pq%3AP459%20%20%3Fwikidataid%20.%20%7D%0A%7D Открыть на query.wikidata.org]
Строка 261: Строка 267:
=== Ранг (rank) ===
=== Ранг (rank) ===


Показать все страны относящиеся у Перми и их [https://www.wikidata.org/wiki/Help:Ranking/ru ранги].
Показать все страны, относящиеся (и относившиеся ранее) к Перми, и их [https://www.wikidata.org/wiki/Help:Ranking/ru ранги].


[https://query.wikidata.org/#SELECT%20DISTINCT%20%3FdoLabel%20%3Fdo%20%3Frank%20WHERE%20%7B%0A%23%20%20VALUES%20%3Frank%20%7B%20wikibase%3ADeprecatedRank%20wikibase%3ANormalRank%20wikibase%3APreferredRank%20%7D%0A%20%20%20%20wd%3AQ915%20%20%20%20%20%20%20p%3AP17%20%3Fvalue.%0A%20%20%20%20%3Fvalue%20%20%20%20%20%20%20ps%3AP17%20%3Fdo%20.%0A%20%20%20%20%3Fvalue%20wikibase%3Arank%20%3Frank%20.%0A%20%20%0A%20%20%20SERVICE%20wikibase%3Alabel%20%7B%0A%20%20%20%20%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%22%20.%0A%20%20%20%7D%0A%7D Открыть на query.wikidata.org]
[https://query.wikidata.org/#SELECT%20DISTINCT%20%3FdoLabel%20%3Fdo%20%3Frank%20WHERE%20%7B%0A%23%20%20VALUES%20%3Frank%20%7B%20wikibase%3ADeprecatedRank%20wikibase%3ANormalRank%20wikibase%3APreferredRank%20%7D%0A%20%20%20%20wd%3AQ915%20%20%20%20%20%20%20p%3AP17%20%3Fvalue.%0A%20%20%20%20%3Fvalue%20%20%20%20%20%20%20ps%3AP17%20%3Fdo%20.%0A%20%20%20%20%3Fvalue%20wikibase%3Arank%20%3Frank%20.%0A%20%20%0A%20%20%20SERVICE%20wikibase%3Alabel%20%7B%0A%20%20%20%20%20bd%3AserviceParam%20wikibase%3Alanguage%20%22ru%22%20.%0A%20%20%20%7D%0A%7D Открыть на query.wikidata.org]
Строка 291: Строка 297:
== Альтернативы SPARQL у Wikidata ==
== Альтернативы SPARQL у Wikidata ==


Нужно отметить что SPARQL подразумевает только запросы на чтение. Часть языка на обновление, добавление и удаление данных это [https://www.w3.org/TR/2013/REC-sparql11-update-20130321/ SPARQL 1.1 Update], в данной статье не рассматривалась.
Нужно отметить, что SPARQL подразумевает только запросы на чтение. Часть языка на обновление, добавление и удаление данных [https://www.w3.org/TR/2013/REC-sparql11-update-20130321/ SPARQL 1.1 Update] в данной статье не рассматривалась.


Для доступа на запись (ботом или массово) вам необходимо ознакомиться с короткой [https://www.wikidata.org/wiki/Wikidata:Bots процедурой регистрации ботов] и [https://www.wikidata.org/wiki/Wikidata:Requests_for_permissions/Bot отправить заявку участника-ботовода].
Для доступа на запись вам необходимо ознакомиться с короткой [https://www.wikidata.org/wiki/Wikidata:Bots процедурой регистрации ботов] и [https://www.wikidata.org/wiki/Wikidata:Requests_for_permissions/Bot отправить заявку участника-ботовода].


# [https://www.npmjs.com/package/wikidata-cli wikidata-cli]
# [https://www.npmjs.com/package/wikidata-cli wikidata-cli]

Текущая версия от 11:27, 28 ноября 2016

Эта страница опубликована в основном списке статей сайта
по адресу http://gis-lab.info/qa/sparql_wikidata.html


SPARQL — это язык запросов к данным, основанных на модели "субъект-предикат-объект" (примечание: "объект" часто заменяется на "значение", особенно в случае количественных предикатов) (в терминах Wikidata элемент-свойство-значения, item-property-values). Wikidata — открытый проект, потенциально интересный в гео-проектах и доступный в виде публичной SPARQL-точки

Инструментарий запросов

Запросы к Wikidata можно составлять с помощью различных SPARQL-клиентов. Ключевая особенность Wikidata — это общедоступная и публичная точка доступа SPARQL, включающая в том числе простой веб-интерфейс.

query.wikidata.org

У сервиса query.wikidata.org есть целое руководство на английском языке https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual и репозиторий для разработчиков https://github.com/wikimedia/wikidata-query-rdf.

Обратите внимание, что результаты запросов можно скачать в формате CSV — хорошее подспорье для более серьёзной работы при помощи других инструментов.

В таблице результатов (в нижней части экрана) можно отфильтровать результаты, используя поиск по всем полям сразу (например, можно попробовать найти "Moscow").

Wikidata

Для помощи по терминологии и модели Wikidata можно посмотреть сюда: Викиданные:Глоссарий.

Структуру элемента (item) и свойства (property) можно найти на англоязычной странице Wikibase/DataModel/Primer.

  • Множественные значения
  • Отсутствующие значения (известно, что значения не может быть) эквивалентны тегам ключ=no из OpenStreetMap - описаны на странице Help:Утверждения
  • Значение не определено (известно, что значение есть, но не известно какое) - описаны на той же странице

Диаграмма русскоязычной терминологии утверждений в Викиданных

Свойства Wikidata

Полный перечень свойств: Wikidata:List_of_properties

Отчёт количества использований каждого свойства - Wikidata:Database_reports/List_of_properties/all

Географические свойства в Wikidata

Полный перечень: Wikidata:List_of_properties/Geographical_feature


Принадлежность стране - https://www.wikidata.org/wiki/Property:P17
Принадлежность админ делению - https://www.wikidata.org/wiki/Property:P131
Координаты (точка) - https://www.wikidata.org/wiki/Property:P625 (при выборке этого свойства появляется возможность представить результаты на карте в нижней части экрана)


Численность населения - https://www.wikidata.org/wiki/Property:P1082


ID отношения из OpenStreetMap - https://www.wikidata.org/wiki/Property:P402
Столица - https://www.wikidata.org/wiki/Property:P36
Город-побратим - https://www.wikidata.org/wiki/Property:P190


Относительная высота https://www.wikidata.org/wiki/Property:P2660
Официальный язык - https://www.wikidata.org/wiki/Property:P37

Российские свойства в Wikidata

Географические элементы в Wikidata

Wikidata Blazegraph

Blazegraph — расширение от Wikidata к Blazegraph, чтобы сделать запросы к Wikibase более эффективными. Имеет лицензию GPLv2.

  • Функция geof:distance возвращает минимальное расстояние между двумя точками.

Элементы SPARQL-запросов

Т.к. исходные данные представляют граф (элемент-свойство-значения) и его модификации (в Wikidata: квалификаторы, ссылки и др.), то большинство SPARQL-запросов строятся вокруг поиска паттернов в графе[1], зачастую нескольких.

Города в России с телефонными кодами

Самый простой пример.

  • 1 строка: SELECT запросы[2] выбирают данные или их часть
  • 2 строка: выбираем субъекты (?item), у которых явно указано, что они в стране - Россия (Q159)
  • 3 строка: выбираем субъекты (?item), у которых явно указано, что они суть - города (Q515)
  • 4-6 строка: т.к. значения предиката "ID отношения из OpenStreetMap" P402 могут быть просто не заполнены у отдельных объектов, такие объекты будут исключены из результатов. Это не совсем интуитивно понятно для людей, привыкших к SQL-запросам (где NULL-значения возвращаются в большинстве случаев). В SPARQL необязательные значения[3] нужно включать в результаты вручную.
  • 7 строка: выбираем все возможные субъекты и объекты у предиката P473 (код города). Примечание о части "?localdialingcode": в Wikidata у Москвы указано сразу два объекта "495" и "499" у предиката P473, поэтому вернутся 2 результата, а не один. В SQL пришлось бы писать JOIN на ровном месте, а в SPARQL его нет вообще.

Открыть на query.wikidata.org

SELECT ?item ?relationid ?itemLabel ?countrydialingcode ?localdialingcode WHERE {
  ?item wdt:P17 wd:Q159.
  ?item wdt:P31 wd:Q515.
  OPTIONAL {
    ?item wdt:P402 ?relationid.
  }
  ?item wdt:P473 ?localdialingcode.
  wd:Q159 wdt:P474 ?countrydialingcode.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

Объекты-побратимы всех российских объектов и их страны

Этот пример призван показать всю простоту JOIN-ов в SPARQL.

Для подходящего первичного ключа (в реляционных терминах) было достаточно найти только сам предикат (город-побратим).

Более того, в отличие от реляционных подходов, мы избавлены от вопросов: "в какой именно таблице хранятся города", "в какой таблице хранится информация о побратимстве". Сложность отличий нормальных форм не сбрасывается сразу на пользователя на уровне языка запросов. Необходимость в тщательном дизайне баз данных (таблиц и отношений) тоже уменьшается (по сравнению с табличным подходом и SQL).

Составители SPARQL-запросов просто исследуют данные запросами, а не думают постоянно, где именно эти данные расположены и как именно они связаны между собой.

  • Строка 2: Академический район будет выбран как находящийся в России.
  • Строка 4: Мелитополь (Украина) будет выбран как побратим Академического района.
  • Строка 7: Исключаем исторические страны у городов-побратимов в результатах

Открыть на query.wikidata.org

SELECT DISTINCT ?wikidataCity ?russianPlace ?country WHERE {
  ?russianPlace wdt:P17 wd:Q159 .
  
  ?russianPlace wdt:P190 ?wikidataCity .
  ?wikidataCity wdt:P17 ?country .
  
  FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}
}
ORDER BY ?russianPlace ?country

Существующие страны и их столицы

В отличие от OpenStreetMap, Wikidata не ограничен "существующими прямо сейчас" объектами. Это можно использовать как хороший пример исключения из результатов.

  • 5 строка: исключаем[4] те страны, которые - исторические
  • 10 строка: результаты упорядочены[5] по названиям на русском или английском языках.

Открыть на query.wikidata.org

SELECT DISTINCT ?country ?countryLabel ?capital ?capitalLabel
WHERE
{
  ?country wdt:P31 wd:Q3624078 .
  FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}
  OPTIONAL { ?country wdt:P36 ?capital } .

  SERVICE wikibase:label { bd:serviceParam wikibase:language "ru", "en" }
}
ORDER BY ?countryLabel

Города примерно с таким же населением, как Пермь

Города, отличающиеся от Перми менее чем на 1000 человек по численности населения.

  • 6 строка: abs[6] это одна из множества возможных функций на числах в тестовых выражениях и фильтрах[7]

Открыть на query.wikidata.org

#defaultView:Map
SELECT DISTINCT ?city ?cityLabel ?populatie2 ?coor WHERE {
  wd:Q915 wdt:P1082 ?populatie .
  ?city wdt:P1082 ?populatie2 .
  ?city wdt:P625 ?coor .
  FILTER (abs(?populatie - ?populatie2) < 1000)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en" }
}

Ранжирование городов по населению

  • Строка 10-17: BIND-конструкция[8] позволяет создать переменную и присвоить ей значение. В данном примере мы использовали другую переменную (?population), чтобы создать новую (?layer)
  • Строка 11: первый из 5 вложенных в "хвостовую часть" IF (условие, значение при истине, значение при не истине)

Открыть на query.wikidata.org

#defaultView:Map
SELECT DISTINCT ?city ?cityLabel ?population ?layer ?coordinates WHERE {
  ?city wdt:P17 wd:Q159.
  ?city wdt:P31 wd:Q515.

  OPTIONAL { ?city wdt:P1082 ?population. }
  
  ?city wdt:P625 ?coordinates.
  
  BIND(
    IF(?population < 500, "500",
    IF(?population < 10000, "10K",
    IF(?population < 100000, "100K",
    IF(?population < 1000000, "1M",
    IF(?population < 10000000, "10M",
    ">20M")))))
    AS ?layer).

  SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en" }
}
ORDER BY 
DESC(?population)

Бывшие столицы государств

Открыть на query.wikidata.org

#defaultView:Map
SELECT DISTINCT ?country ?countryLabel ?capital ?capitalLabel ?coordinates ?ended
WHERE
{
  ?country p:P36 ?stat.
  ?stat ps:P36 ?capital.
  ?capital wdt:P625 ?coordinates.
  OPTIONAL {
    ?country wdt:P582|wdt:P576 ?ended.
  }
  OPTIONAL {
    ?capital wdt:P582|wdt:P576 ?ended.
  }
  OPTIONAL {
    ?stat pq:P582 ?ended.
  }
  FILTER(BOUND(?ended)).
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en". }
}

Города, которые соединяются Транссибирской магистралью или Трансмонгольской железной дорогой

  • 5 строка: конструкция VALUES[9] используется чтобы вручную указать значения у отдельных элементов

Открыть на query.wikidata.org

#defaultView:Map
SELECT ?city ?cityLabel ?coordinates
WHERE
{
   VALUES ?highway { wd:Q559037 wd:Q58767 } 
   ?highway wdt:P2789 ?city .
    ?city wdt:P625 ?coordinates .
   SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en". }
}

Wikidata-префиксы

Полный список префиксов.

Квалификаторы (qualifier)

Если открыть Пермь, то там указанно множество значений у численности населения (P1082), причём все значения — одного ранга (нормальный).

У некоторых из значений численности населения указаны квалификаторы (qualifier) P585 (момент времени) и P459 (метод определения).

  • 2 строка: будут выбраны все 43 высказывания у элемента Q915 и свойства P1082
  • 3 строка: выбираем их значения
  • 4-5 строка: выбираем нужные квалификаторы.

Открыть на query.wikidata.org

SELECT ?val ?qualifier ?wikidataid WHERE {
                 wd:Q915 p:P1082 ?statements           .
            ?statements ps:P1082 ?val      .
            ?statements pq:P585  ?qualifier  .
 OPTIONAL { ?statements pq:P459  ?wikidataid . }
}

Ранг (rank)

Показать все страны, относящиеся (и относившиеся ранее) к Перми, и их ранги.

Открыть на query.wikidata.org

SELECT DISTINCT ?doLabel ?do ?rank WHERE {
#  VALUES ?rank { wikibase:DeprecatedRank wikibase:NormalRank wikibase:PreferredRank }
    wd:Q915       p:P17 ?value.
    ?value       ps:P17 ?do .
    ?value wikibase:rank ?rank .
  
   SERVICE wikibase:label {
     bd:serviceParam wikibase:language "ru" .
   }
}

Примеры запросов

Часть примеров:

Более сложные примеры: https://bitbucket.org/sulab/wikidatasparqlexamples

Альтернативы SPARQL у Wikidata

Нужно отметить, что SPARQL подразумевает только запросы на чтение. Часть языка на обновление, добавление и удаление данных — SPARQL 1.1 Update — в данной статье не рассматривалась.

Для доступа на запись вам необходимо ознакомиться с короткой процедурой регистрации ботов и отправить заявку участника-ботовода.

  1. wikidata-cli
  2. wikidata-sdk
  3. Wikidata API. Заявления у Q915: в JSON или в XML
  4. pywikidata - проект для доступа и на чтение и запись к элементам Wikidata. руководство по созданию ботов и примеры скриптов миграции данных из Википедии и Wikidata.

Источники

Внешние ссылки