1

Continued on from another question here...

I have a(n excerpt from a) construct query below that is successfully pulling records as desired.

CONSTRUCT {
?publication fb:type ?type;
fb:publicationLabel ?publicationLabel;
fb:publicationType ?publicationTypeLabel;
fb:publicationLink ?publicationLink;
}
WHERE {
?publication a bibo:Document .
?publication rdfs:Label ?publicationLabel .
?publication vitro:mostSpecificType ?publicationType .
?publicationType rdfs:Label ?publicationTypeLabel .
?publication obo:ARG_2000028 ?vcard .
?vcard vcard:hasURL ?urllink .
?urllink vcard:url ?publicationLink
}

The above query (trimmed down a bit) currently works fine. I’m now trying to add the following variable: fb:linkInternalExists

To this variable, I want to bind the output of a conditional subquery that looks for a value (we’ll say “internal.url” for this example) within all the possible ?publicationLink values for a specific ?publication.

So the RDF output with the desired addition could return something like the following:

<rdf:Description rdf:about="https://abcd.fgh/individual/publication12345">   
   <fb:publicationLabel>example record 1</fb:publicationLabel>
   <fb:publicationType>journal</fb:publicationType>
   <fb:publicationLink>http://external.url/bcde</fb:publicationType>
   <fb:publicationLink>http://external.url/abcd</fb:publicationType>
   <fb:linkInternalExists>No</fb:linkInternalExists>
</rdf:Description>
<rdf:Description rdf:about="https://abcd.fgh/individual/publication23456">   
   <fb:publicationLabel>example record 2</fb:publicationLabel>
   <fb:publicationType>conference paper</fb:publicationType>
   <fb:publicationLink>http://external.url/2345</fb:publicationType>
   <fb:publicationLink>http://external.url/1234</fb:publicationType>
   <fb:publicationLink>http://internal.url/1234</fb:publicationType>
   <fb:linkInternalExists>Yes</fb:linkInternalExists>
</rdf:Description>

My attempts at adding the required subquery to the above, and successfully bind its output to fb:linkInternalExists, have been unsuccessful. So my question is what would the modified query look like.

Regards

Toolagio
  • 67
  • 9

2 Answers2

1

You don't actually need a subquery for this. All you need is an OPTIONAL pattern combined with a BIND expression.

The optional pattern should specifically look to find an internal link, like so:

OPTIONAL { 
     ?vcard vcard:hasURL ?internal .
     ?internal vcard:url ?internalLink . 
     FILTER(CONTAINS(STR(?internalLlink), "internal.url")
}

or more concisely:

OPTIONAL { 
     ?vcard vcard:hasURL/vcard:url ?internalLink . 
     FILTER(CONTAINS(STR(?internalLlink), "internal.url")
}

This clause will bind a value to ?internalLink if such a link exists, and leave it unbound otherwise. To then convert that to the output form you want, you can add the following conditional BIND-clause:

BIND (IF(BOUND(?internalLink), "Yes", "No") as ?internalLinkExists)

And then of course finally add the following to your CONSTRUCT-clause:

?publication fb:linkInternalExists ?internalLinkExists .
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
  • Upon trying to implement this, the OPTIONAL clause caused the query to crash... as it timed out.
    – Toolagio Jun 06 '18 at 14:54
  • my UNION approach posted above. Any idea how to apply your bind to this new approach? – Toolagio Jun 06 '18 at 15:27
  • @Toolagio glad it helped. Btw it might be better if you posted your eventual solution as an answer yourself (instead of adding it as part of the question). And perhaps then also select that as the accepted answer (you can upvote mine instead of accepting if you still want to give me some credit :)) – Jeen Broekstra Jun 06 '18 at 23:09
1

Upon trying Jeen Broekstra's approach, the query timed out, but it led me to trying other ways to isolate for the internalLink.

I tried the following instead, pulling both the publicationLink and the internalLink variables from distinct UNIONs.

{
?publication a bibo:Document.
?publication obo:ARG_2000028 ?vcard.
?vcard vcard:hasURL ?urllink.
?urllink vcard:url ?publicationLink .
}
UNION {
?publication a bibo:Document .
?publication obo:ARG_2000028 ?vcard .
?vcard vcard:hasURL/vcard:url ?internalLink .
FILTER(CONTAINS(STR(?internalLink), "internal.url"))
}
BIND (IF(BOUND(?internalLink), "Yes", "No") as ?internalLinkExists)

This successfully returned values for ?internalLink, and then the BIND added the Yes/No variable. Job done!

Toolagio
  • 67
  • 9