2013-07-03 4 views
1

У меня есть простой запрос SPARQL:SPARQL «для цикла» в запросе

SELECT DISTINCT ?class1 ?class2 
    WHERE { 
     ?class1 :child ?attribute1 . 
     ?class2 :child ?attribute2 . 
     ?attribute1 :objectName ?name1 . 
     ?attribute2 :objectName ?name2 . 
     FILTER (?name1 = ?name2) 
    } 

В графе RDF, где один из этих «классов» может иметь несколько детей. Я хочу, чтобы найти дубликаты классов, где duplicate означает, что все дети (идентифицированные objectName) в одном классе тоже находятся в другом классе.

Что он делает, возвращает каждый класс, где, по крайней мере, один ребенок существует и в другом классе.

Так что я ищу что-то итерационное для всех детей каждого класса, но пока не нашел пути. Было бы здорово, если бы кто-то мог помочь.

Благодаря

+0

Был обнаружен [недавний вопрос] (http://stackoverflow.com/questions/17323636/comparing-sparql-graphs/17344570#17344570) о вычислении подмножеств в SPARQL. Этот вопрос касался проверки того, является ли один из названных графов подмножеством другого, но некоторые из методов могут применяться здесь, где вы хотите узнать, является ли набор {'? X':' class1: child? X'} подмножество {'? x':' class2: child? x'}. –

+0

Вы сказали «дублировать» классы, но затем «все дети в одном классе тоже в другом». Если все дети второго класса не находятся в первом классе, вы говорите только об _sub_-классе, а не о _equivalent_-классе. Кого вы намеревались? –

ответ

1

Вот несколько примеров данных с четырьмя классами. Первый и второй классы содержат детей с именами «name1» и «name2». Третий класс содержит «name1» и «name3», а четвертый содержит «name3» и «name4». Пятый класс содержит всех детей четвертого, а также «имя5». Итак, первый и второй классы эквивалентны, а четвертый класс - подкласс пятого.

@prefix : <http://example.org/> . 

:class1 :child [ :objectName "name1" ] , 
       [ :objectName "name2" ] . 

:class2 :child [ :objectName "name2" ] , 
       [ :objectName "name1" ] . 

:class3 :child [ :objectName "name1" ] , 
       [ :objectName "name3" ] . 

:class4 :child [ :objectName "name3" ] , 
       [ :objectName "name4" ] . 

:class5 :child [ :objectName "name3" ] , 
       [ :objectName "name4" ] , 
       [ :objectName "name5" ] . 

Вашего описание звучит, как вы на самом деле ищете подклассы, так как вы упоминаете классы все из которых дети и в другом классе. Таким образом, этот запрос SPARQL следует позаботиться о поиске подкласса отношений:

prefix : <http://example.org/> 

select distinct ?c1 ?c2 where { 
    ?c1 :child [] . 
    ?c2 :child [] . 
    NOT EXISTS { ?c1 :child [ :objectName ?name ] . 
       NOT EXISTS { ?c2 :child [ :objectName ?name ] } } 
    FILTER(!sameTerm(?c1, ?c2)) 
} 

Вложенных NOT EXIST модель гарантирует, что только классы мы выбираем такие, что делает NOT EXIST Элемент ?c1, который делает NOT EXIST в ?c2. То есть мы отвергаем любые пары множеств, где является элементом в ?c1, который не находится в ?c2; мы отвергаем любую ?c1,?c2 пару, где ?c1 является не подмножество ?c2, поэтому мы держим только те, где ?c1является подмножество ?c2. Фильтр sameTerm удаляет тривиальные пары ?c,?c, так как все будет подмножеством. Использование командной строки АЗП инструменты Jena, мы получаем следующие результаты:

$ arq --data data.n3 --query query.sparql 
--------------------- 
| c1  | c2  | 
===================== 
| :class4 | :class5 | 
| :class2 | :class1 | 
| :class1 | :class2 | 
--------------------- 

Как и следовало ожидать, :class1 и :class2 являются каждыми подмножествами другой, и :class4 является подмножеством :class5.

Если вы хотите эквивалентные классы, достаточно всего лишь второй NOT EXISTS, чтобы гарантировать, что ?c2 также подмножество ?c1:

prefix : <http://example.org/> 

select distinct ?c1 ?c2 where { 
    ?c1 :child [] . 
    ?c2 :child [] . 
    NOT EXISTS { ?c1 :child [ :objectName ?name ] . 
       NOT EXISTS { ?c2 :child [ :objectName ?name ] } } 
    NOT EXISTS { ?c2 :child [ :objectName ?name ] . 
       NOT EXISTS { ?c1 :child [ :objectName ?name ] } } 
    FILTER(!sameTerm(?c1, ?c2)) 
} 

С этим запросом, мы вернемся только :class1 и :class2:

$ arq --data data.n3 --query query.sparql 
--------------------- 
| c1  | c2  | 
===================== 
| :class2 | :class1 | 
| :class1 | :class2 | 
--------------------- 
+0

Спасибо, это именно то, что мне нужно. Чтобы уточнить, я не говорил о подмножествах, потому что в основном я был после запроса, который дает мне все классы, которые являются точно такими же, но с этого момента просто нет работы. – Grochni

+0

@ Грочный Рад это услышать! Я обновил ответ, чтобы показать эквивалентный запрос класса (но, как вы заметили, это очень тривиально после запроса подкласса). –

2

Обратите внимание, что SPARQL является декларативным языком, а не императив один, так что нет никакого понятия итерации вещей. Вы можете сделать это в API в хранилище RDF, но, по крайней мере, теоретически это выражается в SPARQL, будет более эффективным.

Я думаю, что вам нужно найти все комбинации классов и вычесть те, где какое-то objectName отличается.

Следующее полностью не проверено!

SELECT DISTINCT ?class1 ?class2 
WHERE { 
    ?class1 :child ?attribute1 . 
    ?class2 :child ?attribute2 . 
    MINUS { 
     ?attribute1 :objectName ?name1 . 
     ?attribute2 :objectName ?name2 . 
     FILTER (?name1 != ?name2 && ?attribute1 = ?attribute2) 
    } 
} 

Есть очень маленький шанс, это правильно :), но это должно дать вам некоторое вдохновение.

+0

Я не знал о MINUS, что пригодится, поэтому спасибо. Но проблема в том, что для каждого соответствующего ребенка есть еще один результат, поэтому классы считаются дубликатами, если один из их детей находится в другом классе. – Grochni

Смежные вопросы