user3663894
user3663894

Reputation: 115

Create new triplets based on a query result

[![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

Answers (1)

Valerio Cocchi
Valerio Cocchi

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

Related Questions