Reputation: 115
[![enter image description here][1]][1][1]: https://i.sstatic.net/AG7MM.png
Given the following triple
I would like to get a result :crr1 :hasPart :part1 :crr2 :hasPart :part3
I have tried currently a query below but I don't get the expected results I am trying to put a filter FILTER (?part = ?part2) over the UNION of two queries but failed to get the response I need, what am I doing wrong here?
My sole purpose with the query is to find the missing connections like in this case if CRR1 and CRR2 are connected via Part2 I would then like to create a new CRR that connects Part1 and Part3 depending upon who is the DOB in this example it is CRR1
:crr1 a :XObject .
:crr2 a :XObject .
:crr3 a :XObject .
:crr4 a :XObject .
:part1 a :Part
:part2 a :Part
:part3 a :Part
:part4 a :Part
:part5 a :Part
:crr1 :hasPart :part1 .
:crr1 :hasPart :part2 .
:crr2 :hasPart :part2 .
:crr2 :hasPart :part3 .
:crr3 :hasPart :part3 .
:crr3 :hasPart :part4 .
:crr4 :hasPart :part4 .
:crr4 :hasPart :part5 .
:crr1 :hasType :DOB .
PREFIX : <http://example.com/test#>
construct {
?o :hasPart ?part .
:crr2 :hasPart ?part2 .
}
where
{
{
?o :hasPart ?part
{
select DISTINCT ?o
where {
:crr2 (:hasPart/^:hasPart)+ ?o
FILTER (:crr2 != ?o)
}
}
FILTER EXISTS {?o :hasType :DOB .}
}
UNION
{
:crr2 :hasPart ?part2 .
}
FILTER (?part = ?part2)
}
Upvotes: 0
Views: 85
Reputation: 1966
I am not sure I understand your question properly, but let me try to answer it.
If you are looking to construct a triple between :crr1 and :part3, as the 3rd paragraph of your questions suggests, then you need something like this:
PREFIX : <http://example.com/test#>
CONSTRUCT {?dob :hasPart ?part}
WHERE {
?dob :hasType :DOB .
?dob :hasPart ?p .
?otherCRR :hasPart ?p.
FILTER(?dob != ?otherCRR)
#The above establishes whether the DOB CRR and another one are connected via any part
?otherCRR :hasPart ?part .
FILTER NOT EXISTS {?dob :hasPart ?part}
#This instead makes sure that there isn't already a connection between the DOB and the part in question.
}
If instead you are looking for the parts of :crr2 that are not shared with any other CRR where some connection exists and the other CRR is a DOB, as the 1st paragraph of your question seems to suggest, then you need something like this:
PREFIX : <http://example.com/test#>
CONSTRUCT {
?o :hasPart ?part .
:crr2 :hasPart ?part2 .
}
WHERE{
?o :hasPart ?sharedPart, ?part .
?o :hasType :DOB .
FILTER(?sharedPart != ?part)
:crr2 :hasPart ?sharedPart, ?part2 .
FILTER NOT EXISTS {?o :hasPart ?part2}
FILTER NOT EXISTS {:crr2 :hasPart ?part}
}
This returns the triples you are after. Notice that in your filter, you say that ?part and ?part2 must be the same, so you can't have them as :part1 and :part3, respectively, in your returned triples.
It may also interest you that you can insert your triples directly into the graph with an insert query. Just replace CONSTRUCT with INSERT.
Upvotes: 1