User:Renamerr/SPARQL

Загальне edit

Корисні посилання edit

  • Вікіпедія:Проект:Вікідані (uk)
  • Chapter 2: Querying Linked Data (розділ про SPARQL)
  • «Проміжні вузли» (blank nodes) — щодо [ ] і _:. Два символи [] можна використати замість імені змінної, яка ніде не буде використовуватися; тобто якщо якась змінна зустрічається тільки в одному місці, то її можна замінити на [] і від цього результат запиту не зміниться. Наприклад, :x :q [ :p "v" ] . еквівалентно двом триплетам: :x :q _:b57 . _:b57 :p "v" .

Нормативні посилання (www.w3.org)

SPARQL на wikidata.org, wikibooks.org, wikimedia.org

Wikibase (усі сторінки, що починаються з Wikibase):

Слайди(!):

Запити

Лайфхаки edit

  BIND(xsd:integer(?sub) as ?int). # формування цілочислової ?int з літерної ?sub
  BIND(xsd:integer(SUBSTR(STR(?item), 33)) as ?num) . # у ?num є число - номер елемента (наприклад, число 5 для Q5)
  VALUES ?item { wd:Q1936266 wd:Q1038416 wd:Q414874 wd:Q408023 ...} # формування ?item з декількох значень
  OPTIONAL {?p schema:description ?d FILTER (LANG (?d) = "uk") .}   +   FILTER (!BOUND(?p)) = спосіб 
    отримати всі ?p, що не мають опису на "uk"

     FILTER NOT EXISTS { [] schema:about ?item ; schema:isPartOf <https://uk.wikipedia.org/> } = спосіб
       отримати всі ?item, в яких відсутні посилання на ukwiki
     FILTER((!BOUND(?d)) && (BOUND(?d2))).
     FILTER NOT EXISTS { ... }
     ?item (p:P1766|p:P41|p:P4004) [?qual []] . # що це - (p:P1766|p:P41|p:P4004) - використання АБО?
     ?item p:P38/a wdno:P38 # що це - wdno:  і   p:P38/a wdno:P38  ?
     MINUS { ?item ^schema:about/schema:isPartOf <https://cs.wikipedia.org/> } . # що це - "^" ?

 DISTINCT # гарантує, що кожен рядок таблиці-результату буде унікальним
  • Оптимізація запитів SPARQL:
  • сторінка Wikidata:SPARQL query service/query optimization;
  • щодо ролі ORDER BY (ORDER BY ?something LIMIT 29000 виконується, а LIMIT 29000 - не встигає)
  • інвертована форма. Пряма форма (?child wdt:P22 wd:Q1339) й інвертована форма (wd:Q1339 ^wdt:P22 ?child) дають однакові результати, але інвертована форма може бути набагато швидшою. Приклад запиту (wd:Q9053464 (^pq:P361/^p:P1014)* ?item .); ще приклад (# ?item (p:P1014/pq:P361)* wd:Q1065579 . very very slow || wd:Q1065579 (^pq:P361/^p:P1014)* ?item . # much quicker).

Цікаво, це

 wd:Q22671 ^ps:P171/^p:P171    ?pFamily .
 ?pFamily (^ps:P171/^p:P171)+  ?p .
 wd:Q7432  ^ps:P105/^p:P105    ?p .

працює швидше, ніж

 wd:Q22671 (^ps:P171/^p:P171)+ ?p .
 wd:Q7432  ^ps:P105/^p:P105    ?p .

Елементи SPARQL edit

Триплети edit

Триплет (triple):

суб'єкт + предикат + об'єкт
subject + predicate + object (SPO)
підмет + присудок + додаток

Див. також SPARQL: Triples.

Префікси edit

Префікси (див. RDF Dump Format: Prefixes used, а також RDF Dump Format: Predicates — щодо префіксів у предикатах)

  • p: наприклад, p:P2 для властивості P2, вказує не на об'єкт, а на вузол твердження (statement node); вузол твердження представляє собою одне твердження щодо сутності і має тип wikibase:Statement; твердження може містити ранг, просте значення (див. ps: нижче) твердження, посилання на повне значення, кваліфікатори та посилання.
  • ps: предикатом з таким префіксом і ім'ям властивості (наприклад ps:P2) представляють просте значення (simple value) твердження, об'єктом є просте значення;
 ?item p:P4812/ps:P4812 ?P4812value . # тут поєднано  p:  і  ps:  з однаковим P4812 - що це означає?
 # p:P4812/ps:P4812 ≡ wdt:P4628 або, щонайменше, p:P4812/ps:P4812 ≈ wdt:P4628 (перевірено підстановкою 
 # wdt:P4628 в приклад запиту нижче)
Аналіз результатів двох близьких запитів за темою питання: приклад 1 з p:P4628/ps:P4628 повертає в ?ictv, наприклад, таке: wd:Q9094478, а в приклад 2 з p:P4628 (без /ps:P4628) - таке: wds:Q29002673-E79238AA-01E5-4AC1-B5B7-05A57A52BDA0 (але кількість результатів однакова)
  • psv: повне значення, full value (якщо цього вимагає тип) представлено предикатом з префіксом psv: (наприклад, psv:P2), а об'єктом є вузол повного значення (full value node).
  • pq: The qualifiers are represented by predicates with prefix pq: and the name of the property (e.g. pq:P2) and the object being the simple value of the qualifier.
  • wd: сутність Вікібази — елемент або властивість (наприклад, wd:Q2);
  • wds: вузол твердження (statement node), описує вислів (claim) про сутність (наприклад, wds:Q2-82a6e009-4f93-28dc-3555-38bbfc3afe6a);
  • wdt: з назвою властивості (наприклад, wdt:P9, wd:Q2 wdt:P9 <http://acme.com/>) застосовується у предикатах істинних тверджень (truthy statement predicates)[1], в яких об'єктом є просте значення[2] для твердження (кваліфікатори ігноруються!).
  ?p rdfs:label    ?pLabel .   # ?pLabel - Назва елемента ?p
  ?p skos:altLabel ?alias .    # ?alias - Інші назви елемента ?p
schema:
  ?item schema:description ?descr .         # ?descr - всі наявні описи для елементів Вікіданих ?item
        приклад для schema:description
  ?sitelink schema:name ?wikiarticle_title .    # ?wikiarticle_title - назви статей сайтів (проектів) Вікімедіа
        # для відповідних посилань ?sitelink на ці статті
        # приклад ?wikiarticle_title: Wikipedia:Brudnopis/Wikidane
        приклад для schema:name
  ?sitelink schema:about ?item .     # ?sitelink - посилання на всі статті проектів Вікімедіа (Вікіпедія, 
        # Вікімандри, Вікіцитати тощо), що є в елементах ?item Вікіданих
        # приклад ?sitelink: <https://pl.wikipedia.org/wiki/Wikipedia:Brudnopis/Wikidane>
        приклад для schema:about
  ?p schema:inLanguage  "en" .          # ?
  ?p schema:isPartOf <https://en.wikipedia.org/> # ?
wikibase:
  ?p wikibase:propertyType ?pt . # ?pt - тип властивості : wikibase:Url  ...:ExternalId  ...:String тощо
  ?p wikibase:statements 0 . # - ?p, що мають нуль тверджень
  ?p wikibase:statements ?statementCount . # ?statementCount - кількість тверджень у ?p
  ?p wikibase:sitelinks 0 . # - ?p, що мають нуль посилань на сайти Вікіпедій ([https://query.wikidata.org/#SELECT%20%3Fitem%20WHERE%20%7B%0A%3Fitem%20wikibase%3Asitelinks%20%5B%5D%20.%0AMINUS%20%7B%20%3Fitem%20%28wdt%3AP31%7Cwdt%3AP279%29%20%5B%5D%20%7D%20.%0A%7D%0ALIMIT%201000 приклад])
  ?siteLink wikibase:badge wd:Q20748093 . # - ?siteLink, що мають відзнаку (badge) "перевірена", Q20748093

Запит SELECT edit

Опис edit

Див. SELECT (розділ підручника SPARQL, en).

Запит SELECT виводить вказані змінні і вирази. SELECT є одним з чотирьох типів запитів SPARQL: SELECT, ASK, CONSTRUCT, DESCRIBE.

SELECT складається з двох або трьох частин.

SELECT  ... змінні результату запиту ...
WHERE {
        ... шаблон запиту ...
}
        ... необов'язкові модифікатори запиту ...
GROUP BY ...
HAVING ...
ORDER BY ...
LIMIT ...

Перша частина — це змінні результату запиту (query result variables), які показуються після виконання запиту. Друга частина — це пункт WHERE із шаблоном запиту (query pattern), який визначає вибір даних і генерує змінні. Третя частина — це необов'язкові модифікатори запиту (optional query modifiers).

Підзапити (вкладені запити) edit

Підзапити (subqueries, вкладені запити) беруться у фігурні дужки { SELECT ... WHERE { ... } LIMIT 10 } і не можуть використовувати значення із зовнішнього запиту. Див. також Підзапити (uk, посібник у WD), Subqueries (en, W3C Recommendation, цікаво пошукати "subquer" у цій сторінці).

Є ще іменовані підзапити(?). Див. WITH.

Приклади запису змінних результату запиту edit

1) Property_talk:P4732 (посилання SPARQL (by value))

SELECT   # ?value ?valueLabel ?ct ?items ?itemLabels
    ?value (SAMPLE(?valueLabel) AS ?valueLabel) (SAMPLE(?ct) AS ?ct)
    (GROUP_CONCAT(DISTINCT(STRAFTER(STR(?item), "/entity/")); separator=", ") AS ?items)
    (GROUP_CONCAT(DISTINCT(?itemLabel); separator=", ") AS ?itemLabels)
WHERE 

2) Software Queries

SELECT DISTINCT   # ?item ?name ?classes ?licenses ?platforms
  ?item
  (SAMPLE(COALESCE(?en_label, ?label)) as ?name)
  (GROUP_CONCAT(DISTINCT ?en_class_label; separator=", ") as ?classes)
  (GROUP_CONCAT(DISTINCT ?license_label; separator=", ") as ?licenses)
  (GROUP_CONCAT(DISTINCT ?platform_label; separator=", ") as ?platforms)
WHERE 

WITH, INCLUDE edit

Приклад використання. Структури прикладу:

SELECT ...
WITH { 
  SELECT ...
  WHERE { ... }
} AS %result
WHERE {
  INCLUDE %result
  ...
}

WITH { ... } AS %result — це іменований підзапит (named subquery)?

Ще приклад.

Агрегатування edit

Послідовність агрегатування, GROUP BY, HAVING edit

Послідовність агрегатування (SPARQL 1.1):

  1. Розділити результати на групи на підставі виразу (виразів) у пункті GROUP BY.
  2. Застосувати агрегатні функції в пункті SELECT, щоб отримати ОДИН результат на групу.
  3. Фільтрувати агреговані результати за допомогою пункту HAVING. Приклад: HAVING (?count > 10).

HAVING завжди використовується в поєднанні з GROUP BY. Див. HAVING, [1].

Агрегатні функції edit

SPARQL 1.1 містить такі агрегатні функції: COUNT, SUM, AVG, MIN, MAX, SAMPLE, GROUP_CONCAT[3]:

  • COUNT — кількість елементів. Приклади: COUNT(?painting), COUNT(DISTINCT ?var), COUNT(*) (просто підраховує всі елементи).
  • SUM, AVG сума або середнє значення всіх елементів.
  • MIN, MAX мінімальне або максимальне значення серед усіх елементів. Це працює для всіх типів значень; числа упорядковано чисельно, рядки й інші типи — лексично.
  • SAMPLE довільний елемент.
  • GROUP_CONCAT зчіпляє всі елементи (іноді треба перераховувати незалежні змінні в GROUP BY ...). Див. також SPARQL specification.

Expressions, FILTER, BIND, COALESCE edit

Типи даних:

Рядок (string): "Douglas Adams" або 'Douglas Adams'.

Запис "Douglas Adams"@en формує одномовний англійський текст з рядка (string) "Douglas Adams".

Запис "2012-10-29"^^xsd:dateTime формує дату з рядка (string) "2012-10-29" (datetime не спрацює).

Оператори:
 +, -, *, /          <, >, =, <=, >=, !=          &&, ||

Примітка: "abc" < "abd" є true (лексичне порівняння), також "2016-01-01"^^xsd:dateTime > "2015-12-31"^^xsd:dateTime є true.

BIND(expression AS ?variable) надає результат виразу expression змінній ?variable (зазвичай новій змінній, але можна переписати наявну).

Оператор BOUND(?variable) тестує, чи змінна ?variable пов'язана зі значенням (чи має значення, чи задано для неї значення) і повертає true або false). Це в основному корисно для змінних, які вводяться через OPTIONAL. Змінні зі значенням NaN або INF вважаються пов'язаними. Див. також 11.4.1 bound (11.4 Operators Definitions / 11 Testing Values / SPARQL Query Language for RDF / W3C)

IF(condition,thenExpression,elseExpression)

Функція COALESCE є скороченням для BIND(IF(BOUND(?x), ?x, ?y) AS ?z).

Із FILTER(condition). використовуються лише ті результати, в яких вираз логічного типу condition повертає true.

  FILTER isBLANK(?gender) .   #вибирає всі "порожні" ?gender  (true if term is a blank node)
  FILTER ((LANG(?_countryLabel)) = "uk") .  #вибирає всі українські ?_countryLabel
  FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}  #вибирає всі ?country для яких не існує властивість P31 зі значенням Q3024240

Див. також Внутрішні фільтри (Example: Inner FILTERs) // W3C Recommendation.

OPTIONAL edit

OPTIONAL застосовуємо тоді, коли ми хочемо включити додаткові дані до наявного списку результатів, але не хочемо, щоб це змінило наш список результатів. OPTIONAL не змінює кількість результатів (рядків), але дозволяє збільшити кількість стовців у результаті.

Приклади Software Queries:

 OPTIONAL {?software rdfs:label ?label FILTER(lang(?label) = "en") .}
 OPTIONAL {?class rdfs:label ?en_class_label. FILTER(LANG(?en_class_label) = "en")}
 OPTIONAL {?item rdfs:label ?en_label. FILTER(LANG(?en_label) = "en")}
 OPTIONAL {?item rdfs:label ?label}
 OPTIONAL {?item wdt:P275 ?license. ?license rdfs:label ?license_label . FILTER(LANG(?license_label) = "en")}

Робота з назвами (Labels), SERVICE edit

Є щонайменше два способи отримання назви елемента:

  • через label service (службу назв), недоліком цього способу є пізнє формування назв, що забезпечує лише виведення назв;
  • використовуючи предикат rdfs:label, коли назви зберігаються як звичайні трійки.
# приклад використання rdfs:label
# бачимо, що label service (тобто SERVICE wikibase:label) не використана
SELECT ?human ?label
WHERE
{
  ?human wdt:P31 wd:Q15632617;
         rdfs:label ?label.
  FILTER(LANG(?label) = "en").
  FILTER(STRSTARTS(?label, "Mr. ")).
}
Try it!

MINUS edit

MINUS у цьому запиті вилучає одне значення зі змінної ?p.

SELECT ?p 
WHERE  {
  VALUES ?p { wd:Q4115189 # пісочниця WD
              wd:Q30385394 wd:Q30359318 wd:Q28301653  
  } 
  MINUS { VALUES ?p { wd:Q4115189 } }
}
Try it!

Див. також Заперечення MINUS і MINUS.

Час edit

  "2015-01-01"^^xsd:dateTime <= ?dob && ?dob < "2016-01-01"^^xsd:dateTime #True, якщо час ?dob є в межах 2015 року
  FILTER (?time < "2000-01-01"^^xsd:dateTime) . #вибрати елементи з часом ?time до 2000-го року (виключно)

Запити WDQS для властивостей Вікіданих edit

Шляхи властивостей edit

Шляхи властивостей (див. property paths — W3C Recommendation)[4][5] (SPARQL 1.1)

  • Шляхи властивостей дозволяють триплетним шаблонам (triple patterns) знайти шляхи довільної довжини у графі
  • Предикати поєднуються з операторами, подібними до регулярних виразів:
Форма        Зміст
path1/path2  Forwards path (path1 з наступним path2)
^path1       Backwards path (від об'єкта до суб'єкта)
path1|path2  Either path1 or path2
path1*       path1, повторений нуль або більше разів
path1+       path1, повторений один або більше разів
path1?       path1, необов'язково (нуль або один раз)
!uri         Any predicate except uri
!^uri        Any backwards (object to subject) predicate except uri

Приклади edit

# список елементів з певною властивістю Pxxx (наприклад, P1080) (заготовка запиту)
SELECT ?item ?itemLabel ?value ?valueLabel
{	?item wdt:Pxxx ?value .
	SERVICE wikibase:label { bd:serviceParam wikibase:language "uk,en"  }    
} LIMIT 1000

Для запиту, що нижче, див. також '*' (0 і більше) і '/' в Property paths!

# повний список властивостей Вікіданих, що містять назву українською мовою
SELECT DISTINCT ?a ?aLabel 
WHERE {
 { ?a wdt:P31/wdt:P279* wd:Q18616576;
     rdfs:label ?aLabel.  # ввели aLabel, використовуючи rdfs:label, без SERVICE wikibase:label
 } 
 FILTER ((LANG(?aLabel)) = "uk") .
}
ORDER BY ASC(?a)
LIMIT 10000
Try it!
# У розробці: всі властивості без укр. опису (description)
SELECT ?p ?d ?d2 # ?asset ?pLabel 
  WHERE {
      ?p wikibase:propertyType ?pt .
      ?p  rdfs:label  ?pLabel .
      # OPTIONAL {?p  rdfs:label  ?pLabel FILTER (LANG (?pLabel) = "en") .}
      # ?asset a swg:PRV .
      OPTIONAL {?p schema:description ?d FILTER (LANG (?d) = "uk") .}
      OPTIONAL {?p schema:description ?d2 FILTER (LANG (?d2) = "ru") .}
      OPTIONAL
         {
            # ?asset cim:RSM_IdentifiedObject.name ?name .
            #FILTER (?name = "PRV18")
         }
      #FILTER (!BOUND(?name))
  } GROUP BY ?p ?d ?d2
Try it!
# поряд описи на двох мовах
# використано  wikibase:propertyType  skos:altLabel  schema:description
SELECT ?p ?pLabel ?d ?d2 ?aliases WHERE {
  {
    SELECT ?p ?pt ?d ?d2 (GROUP_CONCAT(DISTINCT ?alias; separator="|") as ?aliases) WHERE {
      ?p wikibase:propertyType ?pt .
      OPTIONAL {?p skos:altLabel ?alias FILTER (LANG (?alias) = "uk")}
      OPTIONAL {?p schema:description ?d FILTER (LANG (?d) = "uk") .}
      OPTIONAL {?p schema:description ?d2 FILTER (LANG (?d2) = "ru") .}
    } GROUP BY ?p ?pt ?d ?d2
  }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "uk,ru". }
}
Try it!

Примітки edit