0

I'm trying to get only ONE relation in the CONSTRUCT.

Please let me introduce the problem.... There is an Actor (actorURI) which has a relation with another Actor (actor2URI). There is only ONE relation possible. With an BIND(IF command i'm trying to get the right URI's for the specific relations and used the string 'blanko' if there is no relation.

Based on a variable (?RelatieSoort) in the data i would like to distinct 5 types of relationships (ChronologischeOpvolger, ChronologischeVoorganger etc.).

I'm propably asking a stupid question. But I don't know what to do.... I hope somebody can help me out. Thanks in advance!

CONSTRUCT {

      ?actorURI a rico:Agent;
          act:heeftRelatie ?relatieURI;
          act:heeftRelatieChronologischeOpvolger ?chronologischeOpvolgerAgentURI;
          act:heeftRelatieChronologischeVoorganger ?chronologischeVoorgangerAgentURI;
          act:heeftRelatieHierarchischBovenliggend ?hierarchischBovenliggendAgentURI;
          act:heeftRelatieHierarchischOnderliggend ?hierarchischOnderliggendAgentURI;
          act:heeftRelatieAssociatief ?associatiefAgentURI.

}
WHERE {

      ?row a mydata:Row ;
          optional { ?row mydata:RelatieUUID ?RelatieUUID }.
          optional { ?row mydata:ActorUUID ?ActorUUID }.
          optional { ?row mydata:Actor2UUID ?Actor2UUID }.
          optional { ?row mydata:RelatieSoort ?RelatieSoort }.
          optional { ?row mydata:Toelichting ?Toelichting }.
          optional { ?row mydata:Begin ?Begin }.
          optional { ?row mydata:Eind ?Eind }.

      # ActorURI
      BIND(IRI(spif:buildString("https://test.nl/id/actordb/actor/{?1}", ENCODE_FOR_URI(?ActorUUID))) AS ?actorURI)

  
      # Actor2URI
      BIND(IRI(spif:buildString("https://test.nl/id/actordb/actor/{?1}", ENCODE_FOR_URI(?Actor2UUID))) AS ?actor2URI) 

    BIND(IF(?RelatieSoort = "Chronologische opvolger", ?actor2URI, "blanko") as ?chronologischeOpvolgerAgentURI)
    BIND(IF(?RelatieSoort = "Chronologische voorganger", ?actor2URI, "blanko") as ?chronologischeVoorgangerAgentURI)  
    BIND(IF(?RelatieSoort = "Hiërarchisch bovenliggend", ?actor2URI, "blanko") as ?hierarchischBovenliggendAgentURI)   
    BIND(IF(?RelatieSoort = "Hiërarchisch onderliggend", ?actor2URI, "blanko") as ?hierarchischOnderliggendAgentURI)  
    BIND(IF(?RelatieSoort = "Associatief", ?actor2URI, "blanko") as ?associatiefAgentURI)   

}
RESULT
https://test/id/actor/actor1 act:heeftRelatieChronologischeOpvolger https://test/id/actor/actor2
?actorURI act:heeftRelatieChronologischeVoorganger "blanko"
?actorURI act:heeftRelatieHierarchischBovenliggend "blanko"
?actorURI act:heeftRelatieHierarchischOnderliggend "blanko"
?actorURI act:heeftRelatieAssociatief "blanko"

In the result above you can see what is happening.... The actual relation is shown (act:heeftRelatieChronologischeOpvolger) and links the two actors with eachother. But the other relations are not existing, but the predicates are shown in the CONSTRUCT. My wish here is to NOT SHOW the other relations in the CONSTRUCT.

Fina83
  • 21
  • 3
  • 1
    ehm, where is the rest of the WHERE part? I mean, you have to bind the variable `?RelatieSoort` to something, don't you? Also, not show the others does not work because you always bind all variables in the WHERE part, thus, there is some binding for each of them. If you just want to have one combination of predicate and object, you should also make the predicate being a variable that is only bound if needed – UninformedUser Jun 29 '20 at 16:40
  • I've added the rest of the WHERE part... – Fina83 Jun 29 '20 at 19:07

2 Answers2

0

The thing is that the query is returning some value for all the defined triples in the CONSTRUCT, either your strings or a blanko string. In case the relationships between the actors does not exist the where clause should return nothing. The bind can return a blank node in this case and then filter if it the case, let's see:

BIND(IF(?RelatieSoort = "Chronologische opvolger", ?actor2URI, bnode()) as ?chronologischeOpvolgerAgentURI)
FILTER(!isBlank(?chronologischeOpvolgerAgentURI))

If you provide us the data set we could help you better.

0

The way to go is to use a var as property in theconstruct, and set its value based on the value match from ?RelatieSoort, e.g. something along the following lines:

CONSTRUCT {
      ?actorURI a rico:Agent;
          act:heeftRelatie ?relatieURI;
          ?prop ?actor2URI.

} where { 
...

    BIND(IF(?RelatieSoort = "Chronologische opvolger", act:heeftRelatieChronologischeOpvolger, 
    IF(?RelatieSoort = "Chronologische voorganger", act:heeftRelatieChronologischeVoorganger, 
    IF(?RelatieSoort = "Hiërarchisch bovenliggend", act:heeftRelatieHierarchischBovenliggend, 
    IF(?RelatieSoort = "Hiërarchisch onderliggend", act:heeftRelatieHierarchischOnderliggend, 
    IF(?RelatieSoort = "Associatief", act:heeftRelatieAssociatief, ?unbound_var))))) as ?prop)   
}

HTH

Damyan Ognyanov
  • 791
  • 3
  • 7