Как групповые шаблоны оцениваются / объединяются в SPARQL - PullRequest
3 голосов
/ 10 мая 2019

Мне интересно, как групповые шаблоны оцениваются в 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))}.
    }

Но теперь снова ... Каким должно быть поведение по умолчанию, когда происходят два последовательных групповых паттерна? присоединяюсь к ним? не обращая внимания на эту несвязанную (нулевую) проблему.

1 Ответ

2 голосов
/ 10 мая 2019

Вы говорите:

Второй тройной паттерн не дает никакого решения

Это правильно.Но вторая группа, {optional {...}}, , дает решение.Это потому, что { OPTIONAL { A } } эквивалентно { {} OPTIONAL { A } }, что эквивалентно {}, если A не имеет решений.Пустая группа {} всегда создает одно решение, которое не связывает никакие переменные, также известное как пустое решение .

Итак ваш первый запрос является объединениемдве последовательности с одним решением.С левой стороны - решение тройного паттерна :hasDirector.На правой стороне пустое решение.В результате перекрестного произведения получается только одна комбинация;условие невидимого соединения удаляет любую комбинацию с конфликтующими привязками переменных, но здесь нет столкновений, поэтому мы сохраняем одну комбинацию.Таким образом, в результате вы видите одну привязку.

Ваш второй запрос отличается от вашего первого запроса.Его основная структура { {TP1} OPTIONAL {TP2} }.Таким образом, левое соединение теперь находится между двумя тройными шаблонами, и никакая неявная дополнительная пустая группа не вставляется до OPTIONAL.

. При редактировании 3 вы добавили условие фильтрации ко второму.группа, которая оценивается как false в пустой привязке.Таким образом, пустая привязка удаляется из последовательности решений, и теперь вторая группа фактически не имеет результатов.Объединение теперь происходит между последовательностью с одним решением и последовательностью с нулевым решением, что тривиально приводит к отсутствию решений.Это объясняет ваши изменения 3.

Unbound: SPARQL не имеет NULL.«Unbound» в SPARQL - это просто условие, при котором переменная вообще не привязана ни к какому значению в конкретном решении.В SQL есть строки и столбцы, поэтому у вас есть ячейки, и ячейки всегда имеют значение, но значением может быть специальное значение NULL.У SPARQL есть строки, но нет столбцов;«столбцы», которые вы видите в результате SELECT, вводятся только в самом конце для целей презентации.но не играют никакой роли во время оценки запроса.В каждой строке (иначе решение) привязано ноль или более переменных, то есть они присвоены значению.И любые другие переменные (бесконечное число) не связаны.

...