Получить все узлы в переходном отношении - PullRequest
5 голосов
/ 30 октября 2010

Можно ли как-нибудь получить список узлов, связанных через транзитивное отношение с SPARQL?У меня есть элементы, которые связаны таким образом:

?a g:eastOf ?b
?b g:eastOf ?c
…

Не все узлы связаны друг с другом, потому что некоторые находятся дальше на юге.Только когда узлы расположены вертикально в одной плоскости, может быть отношение g:eastOf.Это означает, что есть несколько групп узлов, которые не связаны друг с другом.

Я хотел бы получить все эти группы узлов (в основном список списков).Есть ли способ сделать это в SPARQL?Оператор SELECT требует конечного числа переменных и не может каким-либо образом выразить «список» чего-либо.

Меня интересуют только списки, где свойство xsd:integer всех узлов возрастает, когдаидти с запада на восток, но это будет относительно легко после того, как у меня будет решение для моей первой проблемы.

Ответы [ 3 ]

5 голосов
/ 27 ноября 2013

Вы можете сделать хотя бы кое-что из этого с помощью SPARQL 1.1.

Получение списка узлов

Предположим, у вас есть данные, в которых есть две группы точек, которые образуют строки на основена :eastOf:

@prefix : <http://stackoverflow.com/q/4056008/1281433/>

:a :eastOf :b .
:b :eastOf :c .
:c :eastOf :d .

:e :eastOf :f .
:f :eastOf :g .
:g :eastOf :h .

Затем вы можете использовать запрос, подобный следующему:

prefix : <http://stackoverflow.com/q/4056008/1281433/>

select (group_concat(strafter(str(?westernpoint),str(:));separator=", ") as ?colatitudinalPoints)
 where {
  ?easternmost :eastOf* ?westernpoint .
  filter not exists { ?easternmoster :eastOf ?easternmost }
}
group by ?easternmost

, чтобы получить эти результаты:

-----------------------
| colatitudinalPoints |
=======================
| "e, f, g, h"        |
| "a, b, c, d"        |
-----------------------

Есть некоторая обработка строки в

group_concat(strafter(str(?westernpoint),str(:));separator=", ") as ?colatitudinalPoints

, который вам может не понадобиться;Дело в том, что ?westernpoint - это IRI точек к западу от восточной части ?easternmost (который на самом деле включает ?easternmost, поскольку мы использовали * в пути свойств), и затем нам нужно объединить их вместекак-то.Здесь я сделал некоторую обработку строк, чтобы сделать результаты более красивыми.Вы можете так же легко сделать

prefix : <http://stackoverflow.com/q/4056008/1281433/>

select (group_concat(?westernpoint;separator=", ") as ?colatitudinalPoints)
 where {
  ?easternmost :eastOf* ?westernpoint .
  filter not exists { ?easternmoster :eastOf ?easternmost }
}
group by ?easternmost

и получить

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| colatitudinalPoints                                                                                                                                                                      |
============================================================================================================================================================================================
| "http://stackoverflow.com/q/4056008/1281433/e, http://stackoverflow.com/q/4056008/1281433/f, http://stackoverflow.com/q/4056008/1281433/g, http://stackoverflow.com/q/4056008/1281433/h" |
| "http://stackoverflow.com/q/4056008/1281433/a, http://stackoverflow.com/q/4056008/1281433/b, http://stackoverflow.com/q/4056008/1281433/c, http://stackoverflow.com/q/4056008/1281433/d" |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Обеспечение того, что узлы возрастают

Ваше другое требование немного сложнее:

Меня интересуют только списки, в которых свойство xsd: integer всех узлов возрастает при переходе с запада на восток, но это должно быть относительно легко после того, как у меня будет решение для моей первой проблемы.

Тем не менее, если вы можете уточнить, что именно вы хотите в случае чего-то вроде

w --eastof-> x --eastof-> y --eastof-> z
|            |            |            |
5            6            2            3

Например, хотите ли вы отклонить всю цепочку, потому что узлы не 't все по возрастанию, или вы хотите получить две подцепи w x и y z, в которых значения возрастают?Может быть возможно сделать и то, и другое ...

2 голосов
/ 30 октября 2010

Насколько я знаю, вы не можете получить список переменных элементов в качестве решения SPARQL. Я думаю, что самый простой способ сделать то, что вам нужно, это просто получить пары (a, b) из ?a g:eastOf ?b и отсортировать их.

SELECT ?a ?b WHERE {
?a g:eastOf ?b
} ORDER BY ASC(?a) ASC(?b)

Должно быть довольно просто ввести некоторую логику для преобразования списка кортежей в список элементов.

Если вы используете рассуждения с транзитивностью, вы не сможете проследить, каков путь, соединяющий А с С. Если у вас есть что-то вроде (A, g: eastOf, B) и (B, g: eastOf, С). В основном, в этом случае использование рассуждений усложнит ситуацию, поскольку вы хотите создать полный список связанных элементов. Транзитивность в SPARQL даст вам узлы start и end , но вы потеряете возможность отслеживания всех промежуточных точек.

Если у вас нет миллионов утверждений, я думаю, что вышеупомянутый запрос SPARQL плюс некоторая логика для преобразования набора результатов выполнят эту работу.

Отредактировано, чтобы указывать сове Йене +: TransitiveProperty

Итак, сначала убедитесь, что вы загружаете онтологию со следующей аксиомой в свою модель Jena :

g:eastOf rdf:type owl:TransitiveProperty .

Затем включите рассуждение Jena OWL, см. Документацию здесь: Покрытие Jena OWL

И подключите Jena ARQ к вашей модели, чтобы иметь возможность запускать запросы SPARQL.

Как только вы сделали это ... если у вас было что-то вроде ...

:x g:eastOf :y .
:y g:eastOf :t .
:t g:eastOf :z .

и вы выполняете запрос как ...

SELECT ?a ?b WHERE {
?a g:eastOf ?b
} ORDER BY ASC(?a) ASC(?b)

вы получите ...

:x g:eastOf :y .
:x g:eastOf :t .
:x g:eastOf :z .
:y g:eastOf :t .
:y g:eastOf :z .
(...)

Также с Дженой рассмотрите возможность использования Paths свойства . Это тоже сделает работу.

Дайте нам знать, если это работает или если у вас возникнут какие-либо проблемы, ура !!!

0 голосов
/ 30 октября 2010

OpenLink Virtuoso поддерживает такую ​​вещь: Транзитивность в SPARQL Для этого требуется специальный синтаксис в запросах SPARQL.

...