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

Как пишется выражение
Выражение на SPARQL — это одна законченная операция SPARQL: запрос или
обновление. Модель, которой принадлежит контекстный объект, отображается в RDF,
выражение выполняется над ней, а сам объект привязан к ?self.
Правило формулирует вопрос о ?self, на который отвечают «да» или «нет»:
ASK { ?self archimate:Nameable.name ?name . FILTER(STRLEN(STR(?name)) > 0) }
Строки PREFIX писать не нужно. Стандартные префиксы rdf, rdfs, owl и
xsd уже объявлены, как и по одному префиксу на каждую доступную метамодель —
он берётся из собственного префикса метамодели, archimate для ArchiMate. Свои
префиксы объявлять по-прежнему можно; объявление в теле имеет приоритет.
Автодополнение предлагает переменные, уже использованные в теле, классы и свойства доступных метамоделей, а также ключевые слова SPARQL. После переменной в позиции предиката оно сначала предлагает свойства.
Формы запроса и их результат
| Форма | Результат |
|---|---|
ASK | логическое значение |
SELECT | одна строка на решение |
CONSTRUCT | триплеты, которые порождает шаблон |
DESCRIBE | триплеты, описывающие указанные ресурсы |
SELECT с одной проецируемой переменной возвращает сами значения. Если значение
— это IRI объекта, вы получаете объект и можете по нему перейти. SELECT с
несколькими проецируемыми переменными даёт на каждое решение одну строку из пар
имя=значение.
Там, где правило требует логического значения, телом должен быть ASK. SELECT
в этой позиции редактор отмечает ещё до выполнения. В остальных местах
принимается любая корректно построенная операция.
Видимые переменные
?self — объект, для которого вычисляется выражение; он привязан к своему IRI.
Какой это объект, зависит от того, где выражение выполняется, — см.
Консоль выражений.
В обновлении дополнительно привязывается ?g — граф с моделью. Остальные
переменные тела вы привязываете сами.
RDF-представление модели
Выражение видит только ту модель, которой принадлежит ?self. Внутри неё:
- объект — это IRI вида
urn:uuid:<id>; ?o a archimate:BusinessActorсопоставляется с конкретным классом объекта и только с ним — надтипы триплетов не порождают, поэтому шаблон дляarchimate:ArchimateElementне сопоставляется ни с чем;- характеристика адресуется как
prefix:DeclaringClass.feature, поэтому имя бизнес-актора — этоarchimate:Nameable.name, а концы отношения —archimate:ArchimateRelationship.sourceиarchimate:ArchimateRelationship.target; - атрибут — это литерал, хранящий значение в строковой форме, включая числа,
логические значения и литералы перечислений, поэтому сравнивайте через
STR()и приводите черезxsd:integer()и подобные, когда нужно число; - ссылка — это триплет, объектом которого является IRI цели, а вложение — такая
же ссылка, как любая другая, поэтому
archimate:Folder.elementsиarchimate:FolderContainer.foldersобходят дерево модели; - триплеты порождают только заданные характеристики; производные и транзиентные
не дают ничего —
incomingRelationshipsиoutgoingRelationshipsтранзиентны, поэтому добирайтесь до отношения черезsourceиtarget; - обратная ссылка — это шаблон с переменной в позиции объекта:
?subject ?property ?selfнаходит всё, что указывает на?self.
Отображение целиком описано в Модели как RDF.
В запросе триплеты находятся в графе по умолчанию, поэтому конструкция GRAPH
не нужна и ни с чем не сопоставляется.
Изменение модели
Тело обновления описывает изменение, которое выполнит быстрое исправление.
Триплеты модели находятся в графе ?g, и читается потом только он, поэтому все
шаблоны и образцы, работающие с моделью, помещайте внутрь GRAPH ?g:
DELETE { GRAPH ?g { ?self archimate:Nameable.name ?name } }
INSERT { GRAPH ?g { ?self archimate:Nameable.name ?trimmed } }
WHERE { GRAPH ?g { ?self archimate:Nameable.name ?name }
BIND(REPLACE(STR(?name), "^\\s+|\\s+$", "") AS ?trimmed) }
INSERT DATA и DELETE DATA не принимают переменных вообще, поэтому ?self и
?g в них не подставить. Пишите вместо этого
INSERT { GRAPH ?g { ... } } WHERE { ... }.
Несколько операций, разделённых ;, выполняются по порядку над одним и тем же
графом, и ?self и ?g остаются привязанными во всех них.
К модели применяется разница между графом до обновления и после него:
- добавление или удаление триплета атрибута устанавливает или сбрасывает атрибут;
- добавление или удаление триплета ссылки связывает или развязывает два объекта;
- триплет
rdf:typeс новым IRI в субъекте создаёт объект этого класса, а ссылка вложения присоединяет его к модели. IRI выдаётBIND(UUID() AS ?new). Класс должен быть конкретным; - удаление триплета ссылки вложения, удерживающего объект, отсоединяет его от модели.
Добавление, указывающее на несуществующий объект, отмечается как предупреждение и не применяется.
Изменяющее тело порождает набор отдельных изменений. Режим применения задаёт, попадут ли они в модель сразу или будут ждать поштучного подтверждения. См. Консоль выражений.
Примеры
Чтение, где ?self — элемент ArchiMate.
У элемента есть имя:
ASK { ?self archimate:Nameable.name ?name . FILTER(STRLEN(STR(?name)) > 0) }
Элемент с чем-нибудь связан:
ASK {
{ ?r archimate:ArchimateRelationship.source ?self }
UNION
{ ?r archimate:ArchimateRelationship.target ?self }
}
У элемента ровно одно свойство owner:
ASK {
{ SELECT (COUNT(?p) AS ?owners) WHERE {
?self archimate:Properties.properties ?p .
?p archimate:Property.key "owner" .
} }
FILTER(?owners = 1)
}
Документированный элемент должен быть и именованным:
ASK {
FILTER NOT EXISTS {
?self archimate:Documentable.documentation ?doc .
FILTER(STRLEN(STR(?doc)) > 0)
FILTER NOT EXISTS { ?self archimate:Nameable.name ?name .
FILTER(STRLEN(STR(?name)) > 0) }
}
}
Имена следуют соглашению:
ASK {
?self archimate:Nameable.name ?name .
FILTER(REGEX(STR(?name), "^[A-Z][A-Za-z ]*$"))
}
Всё, что реализует этот элемент:
SELECT ?target WHERE {
?r a archimate:RealizationRelationship ;
archimate:ArchimateRelationship.source ?self ;
archimate:ArchimateRelationship.target ?target .
}
Всё, что указывает на этот элемент:
SELECT ?subject ?property WHERE { ?subject ?property ?self }
Всё, до чего можно дойти от этого элемента по отношениям вперёд:
SELECT DISTINCT ?reached WHERE {
?self (^archimate:ArchimateRelationship.source/archimate:ArchimateRelationship.target)+ ?reached
}
Элементы, лежащие в папке, которых не касается ни одно отношение:
SELECT ?element WHERE {
?folder archimate:Folder.elements ?element .
FILTER NOT EXISTS { ?r archimate:ArchimateRelationship.source ?element }
FILTER NOT EXISTS { ?r archimate:ArchimateRelationship.target ?element }
}
Сколько объектов каждого класса содержит модель:
SELECT ?class (COUNT(?object) AS ?count) WHERE { ?object a ?class }
GROUP BY ?class
ORDER BY DESC(?count)
Изменение, где ?self — элемент ArchiMate.
Задать элементу свойство owner, если его нет:
INSERT { GRAPH ?g { ?self archimate:Properties.properties ?new .
?new a archimate:Property ;
archimate:Property.key "owner" ;
archimate:Property.value "unassigned" } }
WHERE { BIND(UUID() AS ?new)
FILTER NOT EXISTS { GRAPH ?g {
?self archimate:Properties.properties ?p .
?p archimate:Property.key "owner" } } }
Подставить заглушку документации, когда её нет:
INSERT { GRAPH ?g { ?self archimate:Documentable.documentation "To be documented" } }
WHERE { FILTER NOT EXISTS { GRAPH ?g {
?self archimate:Documentable.documentation ?doc } } }
Отсоединить элемент и всё, что на него ссылается:
DELETE WHERE { GRAPH ?g { ?self ?p ?o } } ;
DELETE WHERE { GRAPH ?g { ?s ?r ?self } }
Справочник по SPARQL
Принимается полная грамматика SPARQL 1.1 Query и Update, а поверх неё — триплетные термы RDF-star, поддерживаемые движком запросов.
Формы запроса
| Синтаксис | Возвращает | Значение |
|---|---|---|
SELECT ?a ?b WHERE { ... } | строки | перечисленные переменные, по строке на решение |
SELECT * WHERE { ... } | строки | все переменные, использованные в образце |
SELECT (expr AS ?v) WHERE { ... } | строки | вычисленное значение под новым именем |
SELECT DISTINCT ... | строки | дубликаты решений удалены |
SELECT REDUCED ... | строки | дубликаты могут быть удалены |
ASK { ... } | логическое | есть ли у образца хотя бы одно решение |
CONSTRUCT { ... } WHERE { ... } | триплеты | шаблон, инстанцированный для каждого решения |
CONSTRUCT WHERE { ... } | триплеты | сам образец в роли шаблона |
DESCRIBE ?v WHERE { ... } | триплеты | описание каждого связанного ресурса |
DESCRIBE <iri> | триплеты | описание указанного ресурса |
Формы обновления
| Синтаксис | Значение |
|---|---|
INSERT DATA { GRAPH <g> { ... } } | добавить перечисленные триплеты; переменные не допускаются, поэтому ?self и ?g использовать нельзя |
DELETE DATA { GRAPH <g> { ... } } | удалить перечисленные триплеты; переменные не допускаются |
INSERT { ... } WHERE { ... } | добавить шаблон по разу на решение |
DELETE { ... } WHERE { ... } | удалить шаблон по разу на решение |
DELETE { ... } INSERT { ... } WHERE { ... } | удалить и добавить в одной операции |
DELETE WHERE { ... } | удалить ровно то, что сопоставилось с образцом |
WITH <g> DELETE { ... } INSERT { ... } WHERE { ... } | назвать целевой граф один раз для всей операции |
USING <g> | построить граф, который читает предложение WHERE |
USING NAMED <g> | сделать граф адресуемым через GRAPH в предложении WHERE |
LOAD <url> / LOAD <url> INTO GRAPH <g> | прочитать RDF-документ по URL в граф |
LOAD SILENT <url> | то же, но без ошибки, если документ прочитать не удалось |
CLEAR GRAPH <g> / CLEAR DEFAULT / CLEAR NAMED / CLEAR ALL | удалить все триплеты из графов |
DROP GRAPH <g> / DROP DEFAULT / DROP NAMED / DROP ALL | удалить графы |
CREATE GRAPH <g> | создать пустой граф |
ADD <g1> TO <g2> | скопировать триплеты одного графа в другой |
COPY <g1> TO <g2> | заменить содержимое графа содержимым другого |
MOVE <g1> TO <g2> | как COPY, затем удалить исходный граф |
<op> ; <op> | выполнить операции последовательно |
CLEAR, DROP, CREATE, ADD, COPY и MOVE называют графы по IRI и нигде
не принимают ?g, поэтому нацелить их на граф модели нельзя. Триплеты,
записанные не в ?g, по завершении обновления отбрасываются.
Пролог и набор данных
| Синтаксис | Значение |
|---|---|
PREFIX p: <namespace> | привязать префикс CURIE |
BASE <iri> | задать базу для относительных IRI |
FROM <g> | построить граф по умолчанию из перечисленных именованных графов |
FROM NAMED <g> | сделать граф адресуемым через GRAPH |
Запрос читает модель из графа по умолчанию, поэтому конструкция FROM или
FROM NAMED выбирает граф, которого у запроса нет.
Графовые образцы
| Синтаксис | Значение |
|---|---|
?s ?p ?o . | триплетный образец |
?s ?p ?o1, ?o2 . | два объекта при одних субъекте и предикате |
?s ?p1 ?o1 ; ?p2 ?o2 . | два предиката при одном субъекте |
?s a <Class> | сокращение для rdf:type |
{ ... } | группа |
GRAPH ?g { ... } | сопоставление внутри именованного графа |
OPTIONAL { ... } | сопоставить, если возможно, иначе оставить переменные несвязанными |
{ ... } UNION { ... } | решения любой из сторон |
MINUS { ... } | отбросить решения, совместимые с правой стороной |
FILTER(expr) | оставить решения, для которых выражение истинно |
FILTER EXISTS { ... } | оставить решения, для которых образец сопоставляется |
FILTER NOT EXISTS { ... } | оставить решения, для которых он не сопоставляется |
BIND(expr AS ?v) | привязать вычисленное значение |
VALUES ?v { "a" "b" } | задать возможные значения одной переменной |
VALUES (?a ?b) { ("x" 1) ("y" 2) } | задать строки значений для нескольких переменных |
VALUES (?a ?b) { ("x" UNDEF) } | оставить переменную строки несвязанной |
{ SELECT ... WHERE { ... } } | подзапрос, вычисляемый первым |
SERVICE <endpoint> { ... } | передать образец удалённой точке SPARQL |
SERVICE SILENT <endpoint> { ... } | то же, но отказ удалённой точки игнорируется |
[ ?p ?o ] | пустой узел, описанный по месту |
( ?a ?b ) | RDF-коллекция |
Пути по свойствам
| Синтаксис | Значение |
|---|---|
iri | один шаг по свойству |
^iri | один шаг назад — обратная ссылка |
p1/p2 | последовательность шагов |
p1|p2 | любой из путей |
p* | ноль или более шагов |
p+ | один или более шагов |
p? | ноль или один шаг |
!iri | любое свойство, кроме этого |
!(p1|p2) | любое свойство вне набора |
(p) | группировка |
Этот путь обходит граф отношений вперёд на любую глубину:
?self (^archimate:ArchimateRelationship.source/
archimate:ArchimateRelationship.target)+ ?reached
Модификаторы решений
| Синтаксис | Значение |
|---|---|
ORDER BY ?v | сортировка по возрастанию значений переменной |
ORDER BY ASC(expr), ORDER BY DESC(expr) | сортировка по вычисленному ключу |
GROUP BY ?v | сгруппировать решения перед агрегированием |
GROUP BY (expr AS ?v) | группировка по вычисленному ключу |
HAVING(expr) | оставить группы, для которых выражение истинно |
LIMIT n | не более n строк |
OFFSET n | пропустить первые n строк |
Операторы
В порядке убывания приоритета.
| Синтаксис | Возвращает | Значение |
|---|---|---|
!a, +a, -a | логическое, число | отрицание, знак |
a * b, a / b | число | умножение, деление |
a + b, a - b | число | сложение, вычитание |
a = b, a != b | логическое | равенство и неравенство значений |
a < b, a <= b, a > b, a >= b | логическое | порядок |
a IN (x, y) | логическое | принадлежность списку |
a NOT IN (x, y) | логическое | отсутствие в списке |
a && b | логическое | конъюнкция |
a || b | логическое | дизъюнкция |
Литералы и термы
| Синтаксис | Значение |
|---|---|
<http://example.org/x> | абсолютный IRI |
prefix:local | CURIE относительно объявленного префикса |
a | rdf:type |
?v, $v | переменная |
"text", 'text' | строковый литерал |
"""text""", '''text''' | многострочный строковый литерал |
"text"@en | литерал с языковым тегом |
"5"^^xsd:integer | литерал с явным типом данных |
42, -3 | целочисленный литерал |
4.5 | десятичный литерал |
1.0e6 | литерал двойной точности |
true, false | логический литерал |
_:b1 | именованный пустой узел |
[] | анонимный пустой узел |
() | rdf:nil, пустая коллекция |
# text | комментарий до конца строки |
<<?s ?p ?o>> | триплетный терм |
Функции над термами, проверки и преобразования
| Синтаксис | Возвращает | Значение |
|---|---|---|
STR(term) | строка | лексическая форма литерала или IRI |
LANG(literal) | строка | языковой тег, пустой, если его нет |
LANGMATCHES(tag, range) | логическое | соответствует ли языковой тег диапазону |
DATATYPE(literal) | IRI | тип данных литерала |
BOUND(?v) | логическое | есть ли у переменной значение |
IRI(string), URI(string) | IRI | построить IRI из строки |
BNODE(), BNODE(string) | пустой узел | новый пустой узел |
UUID() | IRI | новый IRI вида urn:uuid: |
STRUUID() | строка | новый UUID в виде строки |
isIRI(term), isURI(term) | логическое | является ли терм IRI |
isBLANK(term) | логическое | является ли терм пустым узлом |
isLITERAL(term) | логическое | является ли терм литералом |
isNUMERIC(term) | логическое | является ли терм числовым литералом |
sameTerm(a, b) | логическое | тождество термов, строже чем = |
IF(cond, a, b) | любое | условное значение |
COALESCE(a, b, ...) | любое | первый аргумент, вычисляемый без ошибки |
STRDT(string, iri) | литерал | литерал с заданным типом данных |
STRLANG(string, tag) | литерал | литерал с заданным языковым тегом |
xsd:string(v) | литерал | приведение к строке |
xsd:boolean(v) | литерал | приведение к логическому значению |
xsd:integer(v), xsd:decimal(v), xsd:double(v), xsd:float(v) | литерал | приведение к числу |
xsd:long(v), xsd:int(v), xsd:short(v), xsd:byte(v) | литерал | приведение к целому заданного размера |
xsd:unsignedLong(v), xsd:unsignedInt(v), xsd:unsignedShort(v), xsd:unsignedByte(v) | литерал | приведение к беззнаковому целому |
xsd:nonNegativeInteger(v), xsd:positiveInteger(v), xsd:nonPositiveInteger(v), xsd:negativeInteger(v) | литерал | приведение к целому с ограничением знака |
xsd:date(v), xsd:dateTime(v) | литерал | приведение к дате или дате со временем |
Строковые функции
| Синтаксис | Возвращает | Значение |
|---|---|---|
STRLEN(s) | число | количество символов |
SUBSTR(s, start) | строка | от позиции (с единицы) до конца |
SUBSTR(s, start, length) | строка | заданное количество символов |
UCASE(s), LCASE(s) | строка | смена регистра |
STRSTARTS(s, prefix) | логическое | начинается ли строка с префикса |
STRENDS(s, suffix) | логическое | заканчивается ли строка суффиксом |
CONTAINS(s, part) | логическое | содержит ли строка фрагмент |
STRBEFORE(s, part) | строка | что предшествует первому вхождению |
STRAFTER(s, part) | строка | что следует за первым вхождением |
ENCODE_FOR_URI(s) | строка | процентное кодирование для URI |
CONCAT(s1, s2, ...) | строка | соединить аргументы |
REGEX(s, pattern) | логическое | сопоставляется ли шаблон |
REGEX(s, pattern, flags) | логическое | то же, с флагами вроде "i" |
REPLACE(s, pattern, replacement) | строка | заменить каждое совпадение |
REPLACE(s, pattern, replacement, flags) | строка | то же, с флагами |
STRAFTER(STR(?name), "-") возвращает то, что следует за первым дефисом имени.
Числовые функции
| Синтаксис | Возвращает | Значение |
|---|---|---|
ABS(n) | число | модуль |
ROUND(n) | число | ближайшее целое |
CEIL(n) | число | наименьшее целое, не меньшее n |
FLOOR(n) | число | наибольшее целое, не большее n |
RAND() | число | число двойной точности от 0 до 1 |
Функции даты и времени
| Синтаксис | Возвращает | Значение |
|---|---|---|
NOW() | dateTime | текущие дата и время |
YEAR(d), MONTH(d), DAY(d) | число | составляющие даты |
HOURS(d), MINUTES(d), SECONDS(d) | число | составляющие времени |
TIMEZONE(d) | длительность | часовой пояс как длительность |
TZ(d) | строка | часовой пояс в исходной записи |
Хеш-функции
| Синтаксис | Возвращает | Значение |
|---|---|---|
MD5(s) | строка | дайджест MD5 в шестнадцатеричном виде |
SHA1(s) | строка | дайджест SHA-1 |
SHA256(s) | строка | дайджест SHA-256 |
SHA384(s) | строка | дайджест SHA-384 |
SHA512(s) | строка | дайджест SHA-512 |
Функции над триплетными термами
Эти функции не имеют записи с ключевым словом. Каждая вызывается по своему IRI,
который записывается через уже объявленный префикс rdf.
| Синтаксис | Возвращает | Значение |
|---|---|---|
rdf:Statement(s, p, o) | триплетный терм | построить триплетный терм |
rdf:isTriple(t) | логическое | является ли терм триплетным термом |
rdf:subject(t) | терм | субъект триплетного терма |
rdf:predicate(t) | IRI | предикат триплетного терма |
rdf:object(t) | терм | объект триплетного терма |
Агрегаты
| Синтаксис | Возвращает | Значение |
|---|---|---|
COUNT(?v) | число | количество связанных значений |
COUNT(*) | число | количество решений в группе |
COUNT(DISTINCT ?v) | число | количество различных значений |
SUM(?v), AVG(?v) | число | сумма и среднее |
MIN(?v), MAX(?v) | любое | наименьшее и наибольшее значение |
SAMPLE(?v) | любое | одно значение из группы |
GROUP_CONCAT(?v) | строка | значения, соединённые пробелом |
GROUP_CONCAT(?v; SEPARATOR=", ") | строка | значения, соединённые заданным разделителем |
DISTINCT можно написать внутри любого агрегата, например
GROUP_CONCAT(DISTINCT ?name; SEPARATOR=", ").
Ещё четыре агрегата не имеют записи с ключевым словом и вызываются по IRI:
| Синтаксис | Возвращает | Значение |
|---|---|---|
<http://rdf4j.org/aggregate#stdev>(?v) | число | выборочное стандартное отклонение |
<http://rdf4j.org/aggregate#stdev_population>(?v) | число | стандартное отклонение генеральной совокупности |
<http://rdf4j.org/aggregate#variance>(?v) | число | выборочная дисперсия |
<http://rdf4j.org/aggregate#variance_population>(?v) | число | дисперсия генеральной совокупности |