Мне интересно, как групповые шаблоны оцениваются в SPARQL. Мое предположение состояло в том, что каждый шаблон группы оценивается отдельно, а затем привязки решений из групп объединяются. Однако, похоже, что это не так.
Давайте возьмем данные этого примера:
:film1 :hasDirector :director1.
Давайте рассмотрим следующий пример:
select * where {
{?a :hasDirector ?c.}
{optional {?c :fromCountry ?e}}.
}
Я бы предположил, что каждая группа будет оцениваться отдельно, а затем результаты обеих групп будут объединены. с точки зрения реляционной алгебры это выглядело бы как first_group INNER-JOIN second_group
. Однако дело не в этом ...
Оценка каждой группы в отдельности; шаблон первой группы дает решение: ?a = :film1, ?c = :director1
. Второй тройной паттерн does not yield any solution
. Теперь, если мое предположение было верным, объединение результатов не вернуло бы никакого решения. Однако этот запрос возвращает одно решение с ?a = :film1 ,?c = :director1, ?e unbound
.
Этот результат такой же, как если бы не было используемых групп {}
, также как и при выполнении следующего запроса:
select * where {
?a :hasDirector ?c.
optional {?c :fromCountry ?e}.
}
Последний запрос (снова для облегчения понимания) first_group LEFT-OUTER-JOIN second_group
.
Как групповые шаблоны оцениваются в SPARQL? Что мне здесь не хватает?
PS. Я использую GraphDB для тестирования ...
EDIT1:
Теперь попытка получить алгебру запросов через Jena ARQ ... кажется, подтверждает то, что я ожидал?
Вот что я получил от Jena ARQ для первой алгебры запросов:
(join
(bgp (triple ?a <http://www.example.com/hasDirector> ?c))
(leftjoin
(table unit)
(bgp (triple ?c <http://www.example.com/fromCountry> ?e))))
Второй запрос:
(leftjoin
(bgp (triple ?a <http://www.example.com/hasDirector> ?c))
(bgp (triple ?c <http://www.example.com/fromCountry> ?e)))
EDIT2:
Jena дает те же результаты GraphDB для первого запроса, хотя алгебра выглядит так, как я только что показал.
EDIT3:
Может ли это быть причиной? обработка несвязанных значений (как pre-null в реляционной БД) в соединениях довольно странная. См. Приложение C здесь .
EDIT4:
Кажется, проблема в том, что указано в EDIT3 добавление FILTER (BOUND (?c))
в первом запросе даст ожидаемые результаты!
select * where {
{?a :hasDirector ?c.}
{optional {?c :fromCountry ?e} FILTER (BOUND (?c))}.
}
Но теперь снова ... Каким должно быть поведение по умолчанию, когда происходят два последовательных групповых паттерна? присоединяюсь к ним? не обращая внимания на эту несвязанную (нулевую) проблему.