SPARQL на примерах Wikidata
SPARQL это язык запросов к данным, основанных на модели "субъект-предикат-значение". Wikidata - это открытый проект, потенциально интересный в гео-проектах и доступный в виде публичной SPARQL-точки
Инструментарий запросов
Запросы к Wikidata можно составлять с помощью различных SPARQL клиентов, но ключевой особенностью Wikidata это общедоступная и публичная точка доступа SPARQL. Более того, был написан простой web интерфейс к ней.
query.wikidata.org
https://query.wikidata.org - веб-интерфейс.
У этого инструмента есть целое руководство на английском языке https://www.mediawiki.org/wiki/Wikidata_query_service/User_Manual и репозиторий для разработчиков https://github.com/wikimedia/wikidata-query-rdf.
Обратите внимание, что результаты запросов можно скачать в формате CSV - хорошее подспорье для более серьёзной работы с помощью других инструментов.
В таблице результатов (в нижней части экрана) можно отфильтровать результаты, используя поиск по всем полям сразу (например, можно попробовать найти "Moscow").
Wikidata
В рамках gis-lab в первую очередь интересуют предикаты (свойства объектов) относящиеся к географическим свойствам.
Предикаты Wikidata
- дата прекращения существования - https://www.wikidata.org/wiki/Property:P576
- дата окончания - https://www.wikidata.org/wiki/Property:P582
Географические предикаты в Wikidata
- Координаты (точка) - https://www.wikidata.org/wiki/Property:P625 (при выборке этого свойства появляется возможность представить результаты на карте в нижней части экрана)
- ID отношения из OpenStreetMap - https://www.wikidata.org/wiki/Property:P402
- принадлежность стране - https://www.wikidata.org/wiki/Property:P17
- столица - https://www.wikidata.org/wiki/Property:P36
- численность населения - https://www.wikidata.org/wiki/Property:P1082
- официальный язык - https://www.wikidata.org/wiki/Property:P37
- город-побратим - https://www.wikidata.org/wiki/Property:P190
Географические объекты в Wikidata
- континент - https://www.wikidata.org/wiki/Q5107
- суверенное государство - https://www.wikidata.org/wiki/Q3624078
- историческое государство - https://www.wikidata.org/wiki/Q3024240
- город - https://www.wikidata.org/wiki/Q515
- северный полюс - https://www.wikidata.org/wiki/Q934
- южный полюс - https://www.wikidata.org/wiki/Q933
Элементы SPARQL запросов
Города в России с телефонными кодами
Самый простой пример.
- 1 строка: SELECT запросы[1] выбирают данные или их часть
- 2 строка: выбираем субъекты (?item) у которых явно указано, что они в стране - Россия (Q159)
- 3 строка: выбираем субъекты (?item) у которых явно указано, что они суть - города (Q515)
- 4-6 строка: т.к. значения предиката "ID отношения из OpenStreetMap" P402 могут быть просто не заполнены у отдельных объектов, такие объекты будут исключены из результатов. Это не совсем интуитивно понятно для людей, привыкших к SQL-запросам (где NULL-значения возвращаются в большинстве случаев). В SPARQL необязательные значения[2] нужно включать в результаты вручную.
- 7 строка: выбираем все возможные субъекты и объекты у предиката P473 (код города). Примечание о части "?localdialingcode": в Wikidata у Москвы указано сразу два объекта "495" и "499" у предиката P473, поэтому вернутся 2 результата, а не один. В SQL пришлось бы писать JOIN на ровном месте, а в SPARQL его нет вообще.
SELECT ?item ?relationid ?itemLabel ?localdialingcode WHERE {
?item wdt:P17 wd:Q159.
?item wdt:P31 wd:Q515.
OPTIONAL {
?item wdt:P402 ?relationid.
}
?item wdt:P473 ?localdialingcode.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Объекты-побратимы всех Российских объектов и их страны
Этот пример призван показать всю простоту JOIN-ов в SPARQL.
Для подходящего первичного ключа (в реляционных терминах) было достаточно найти только сам предикат (город-побратим).
Более того, в отличие от реляционных подходов, мы избавлены от вопросов: "в какой именно таблице хранятся города", "в какой таблице хранится информация о побратимстве". Сложность отличий нормальных форм не сбрасывается сразу на пользователя на уровне языка запросов. Необходимость в тщательном дизайне баз данных (таблиц и отношений) тоже уменьшается (по сравнению с табличным подходом и SQL).
Составители запросов SPARQL просто исследуют данные запросами, а не постоянно думают где именно эти данные расположены и как именно их будут связывать.
Строка 2: обратите внимание на данные в Wikidata: Мелитополь (Украина) указан как побратим московского района Академический район. Академический район будет выбран как находящийся в России. Строка 7: исключаем исторические страны у городов-побратимов в результатах
SELECT DISTINCT ?wikidataCity ?russianCityLabel ?wikidataCityLabel ?countryLabel WHERE {
?russianCity wdt:P17 wd:Q159 .
?russianCity wdt:P190 ?wikidataCity .
?wikidataCity wdt:P17 ?country .
FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en" }
}
ORDER BY ?russianCityLabel ?countryLabel
Существующие страны и их столицы
В отличие от OpenStreetMap, Wikidata не ограничен "существующими прямо сейчас" объектами. Это можно использовать как хороший пример исключения из результатов.
- 5 строка: исключаем[3] те страны, которые - исторические
- 10 строка: результаты упорядочены[4] по названиям на русском или английском
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 населения
#defaultView:Map
SELECT DISTINCT ?city ?cityLabel ?populatie2 ?coor WHERE {
wd:Q915 wdt:P1082 ?populatie .
?city wdt:P1082 ?populatie2 ;
wdt:P625 ?coor .
FILTER (abs(?populatie - ?populatie2) < 1000)
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en" }
}
Бывшие столицы государств
#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[5] используется чтобы вручную указать значения у отдельных элементов[6]
#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, отсортированные по убыванию их Wikidata идентификатора
- Объекты в более чем 3000 км от южного полюса, но всё ещё относящиеся к Антарктике
- Страны по убыванию населения
- Самый населённый город в каждой стране
- Количество записей о людях в Викиданных на каждый миллион населения в данной стране
Внешние ссылки
- ↑ https://www.w3.org/TR/sparql11-query/#QueryForms
- ↑ https://www.w3.org/TR/sparql11-query/#optionals
- ↑ https://www.w3.org/TR/sparql11-query/#negation
- ↑ https://www.w3.org/TR/sparql11-query/#solutionModifiers
- ↑ https://www.w3.org/TR/sparql11-query/#inline-data
- ↑ http://www.snee.com/bobdc.blog/2012/09/sparql-11s-new-values-keyword.html