Given are Objects :A, :B and :C which have properties assigned, whereas these properties are not scalar themselves but are also objects with key and value properties.
@prefix x: <http://example.com/example#>
x:A x:hasProp x:Prop1 .
x:Prop1 x:Key "1" .
x:Prop1 x:Value "AA" .
x:B x:hasProp x:Prop2 .
x:Prop2 x:Key "1" .
x:Prop2 x:Value "AA" .
x:C x:hasProp x:Prop3 .
x:C x:hasProp x:Prop4 .
x:Prop3 x:Key "1" .
x:Prop3 x:Value "AA" .
x:Prop4 x:Key "2" .
x:Prop4 x:Value "BB" .
How can I assert that :A and :B have the same properties whereas :A and :C not? I'm new to SPARQL and I have no idea... I tried something like :
prefix x: <http://example.com/example#>
select ?another ?k ?v
{x:A x:hasProp ?p .
?p ?k ?v .
?another x:hasProp ?p2 .
?p2 ?k ?v .
}
but I think it's a wrong way. It also returns :C.
How can one easily compare two sets in SPARQL?
Additional question: The query from the answer 1 works fine but only if :A used directly. Using a variable in place of :A makes :C also to qualify. Why?
I mean: insert some condition to find :A
prefix : <http://example.com/example#>
INSERT DATA {:A rdfs:label "A"}
and then use a variable in place of :A
prefix : <http://example.com/example#>
select ?other ?k ?v {
#-- Find ?other such that :A and ?other have
#-- some property in common,
?a rdfs:label "A"
?a :hasProp [ :Key ?k ; :Value ?v ] .
?other :hasProp [ :Key ?k ; :Value ?v ] .
#-- but remove any ?other such that:
filter not exists {
#-- (i) :A has a property that ?other doesn't;
{
?a :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
union
#-- or (ii) ?other has a property that :A doesn't.
{
?other :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists {
?a :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
}
}
Update:
prefix : <http://example.com/example#>
INSERT DATA {
:A rdfs:label "A" .
:A :hasProp :Prop1 .
:Prop1 :Key "1" .
:Prop1 :Value "AA" .
:B :hasProp :Prop2 .
:Prop2 :Key "1" .
:Prop2 :Value "AA" .
:C :hasProp :Prop3 .
:C :hasProp :Prop4 .
:Prop3 :Key "1" .
:Prop3 :Value "AA" .
:Prop4 :Key "2" .
:Prop4 :Value "BB" .
}
Query using :A
prefix : <http://example.com/example#>
select ?other ?k ?v {
:A :hasProp [ :Key ?k ; :Value ?v ] .
?other :hasProp [ :Key ?k ; :Value ?v ] .
filter not exists {
{ :A :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
union
{
?other :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
}
}
Answer:
-------------------
|other| k | v
|A | "1" | "AA"
|B | "1" | "AA"
-------------------
Query using variable ?a:
prefix : <http://example.com/example#>
select ?other ?k ?v {
?a rdfs:label "A" .
?a :hasProp [ :Key ?k ; :Value ?v ] .
?other :hasProp [ :Key ?k ; :Value ?v ] .
filter not exists {
{ ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
union
{
?other :hasProp [ :Key ?kk ; :Value ?vv ] .
filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
}
}
}
}
returns
other k v
A "1" "AA"
B "1" "AA"
C "1" "AA"