简体   繁体   中英

Dynamic predicates in SPARQL CONSTRUCT

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.

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.

The way to go is to use a var as property in the construct , and set its value based on the value match from ?RelatieSoort , eg 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM