Возьмите этот график:SPARQL алгебра: Исключение узлов на основе троек они
:thing1 a :Foo ;
:has :A ;
:has :B .
:thing2 a :Foo ;
:has :B ;
:has :A .
:thing3 a :Foo ;
:has :A ;
:has :B ;
:has :C .
Я хочу, чтобы выбрать :thing1
и :thing2
, но НЕ:thing3
.
Вот запрос SPARQL, который я написал, который работает. Есть лучший способ сделать это?
SELECT ?foo WHERE {
?foo a :Foo ;
:has :A ;
:has :B .
MINUS {
?foo a :Foo ;
:has :A ;
:has :B ;
:has ?anythingElse .
FILTER(?anythingElse != :A && ?anythingElse != :B)
}
}
Я действительно считаю, что это на самом деле лучше, потому что минус-блок из исходного сообщения будет искать весь граф, тогда как фильтр не существует, будет искать только (и затем удалять) соответствующие тройки из результатов внешнего блока. Другими словами, это решение должно иметь лучшую производительность, поскольку оно удаляет тройки, которые ': has? Other' из подмножества троек, которые': имеют: A,: B'. Не могли бы вы добавить это объяснение в свое решение?Тогда я был бы рад принять его как ответ :) –
Это немного сложнее, чем это :-). Оптимизатор может обнаружить, что форма MINUS может быть преобразована в форму FILTER NOT EXIST или может видеть, что блок MINUS может совместно использовать вычисления с основной частью и использовать это. Тем не менее, это сложная оптимизация (они не всегда работают), и я не считаю, что многие системы пытаются их использовать. В ARQ, FILTER NOT EXISTS является формой быстрее для этого случая, когда MINUS имеет множество общих черт. – AndyS