Как я могу получить внутреннее соединение двух графов в Apache Jena с помощью SPARQL без UNION / FILTER?

У меня есть онтология на основе Apache Jena, и в ней есть два именованных графа:

m_p

p1    pred1    mp1
p2    pred1    mp1
p3    pred1    mp2
p4    pred1    mp2
p5    pred1    mp3
p6    pred1    mp3

и m_p_s

mp1   pred2    w:frnd
mp1   pred2    w:fdlfkdl
mp2   pred2    w:kdsjflk
mp2   pred2    w:jflksdlkj
mp3   pred2    w:frnd
mp3   pred2    w:fjksldjfls

и я хочу получить все тройки в m_p, объекты которых являются предикатами в m_p_s, а объект этого предикаты в m_p_s - w: frnd

Другими словами, я хочу сделать запрос, который возвращает (результаты с) p1, p2, p5 и p6 из m_p и не возвращает значения p3 и p4.

Я пытаюсь сделать это с помощью вложенных запросов, но это не работает: например,

SELECT $subj $pred $pr
FROM NAMED named_graph:m_p
WHERE
{
    SELECT $pr
    WHERE
    {
       GRAPH named_graph:m_p_s { $pr $pred0 w:frnd }
    }
}

возвращает пустой результат. Я пробовал разные вещи, но либо получаю ошибку, либо пустой результат, либо все в m_p.

Я не хочу использовать UNION или FILTER по соображениям производительности.

У тебя есть идеи, как я могу это сделать?

С уважением, Стефан


person Jimo    schedule 13.10.2017    source источник
comment
Примечание: я пропустил объявление префикса, чтобы сократить сообщение для лучшей читаемости. Например. 'named_graph' - это префикс с URI ‹ao.com/ namedGraph  -  person Jimo    schedule 13.10.2017
comment
Ваш внешний запрос не выбирает тройной шаблон. Откуда оболочка привязки $subj и $pred? Таким образом, не должно ли быть ?subj ?pred ?pr перед подвыбором? Т.е. SELECT ?subj ?pred ?pr FROM NAMED named_graph:m_p WHERE { ?subj ?pred ?pr { SELECT ?pr WHERE { GRAPH named_graph:m_p_s { ?pr ?pred0 w:frnd } } } } Я протестирую его через 2 часа, когда вернусь, может быть, что-то тоже не хватает в графиках   -  person UninformedUser    schedule 13.10.2017
comment
Пожалуйста, не сокращайте запросы - убедитесь, что их можно вырезать и вставить, чтобы читатели могли получить именно то, что вы используете.   -  person AndyS    schedule 13.10.2017


Ответы (2)


Внутренний SELECT не нужен: он скрывает второе использование? P, но это можно сделать, используя другое имя:

SELECT ?s ?p ?o
FROM named_graph:m_p
FROM NAMED named_graph:m_p_s
{
   ?s ?p ?o
   GRAPH named_graph:m_p_s { ?o ?px w:frnd }
}
person AndyS    schedule 13.10.2017

Я не понимаю, что вы имеете в виду, говоря «Я хочу получить все тройки в m_p, объекты которых являются предикатами в m_p_s». Если вы имеете в виду «чьи объекты являются субъектами в m_p_s», это будет иметь больше смысла:

SELECT *
FROM named_graph:m_p
FROM NAMED named_graph:m_p_s
WHERE
{
  ?s ?p ?o
  {
     SELECT ?o WHERE {
       GRAPH named_graph:m_p_s { ?o ?p w:frnd }
      }
  }
}
person UninformedUser    schedule 13.10.2017