1

Consider the following SPARQL update:

INSERT {
    ?performance
        mo:performer ?performer ; # optional
        mo:singer    ?singer ;    # optional
        mo:performance_of [
            dc:title ?title ; # mandatory
            mo:composed_in [ a mo:Composition ;
                mo:composer ?composer # optional
            ]
        ]
}
WHERE {}

If I do not provide values (e.g. in Jena's ParameterizedSparqlString.setIri() for ?performer, ?singer, or ?composer, this update won't insert statements with the corresponding objects, which is as intended.

But how can I suppress [] a mo:Composition as well if ?composer is missing. Creating it in a second INSERT whose WHERE filters on ISIRI(?composer) doesn't seem to be an option because that INSERT won't know the blank node that has already been created by the first one.

So how can I support this kind of optional parameters in a single SPARQL update? E.g., is there any means for "storing" the blank node between two INSERTs?

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
Drux
  • 11,992
  • 13
  • 66
  • 116
  • Offhand, I *think* that an insert (like a construct) will process the triples that work, and ignore the ones that don't. E.g., if you have `?person :name ?name ; :age ?age` and you only have a binding for `?age` and `?person`, you *should* get the the `?person :age ?age` triple, and no `?person :name ...` triples. – Joshua Taylor Jan 02 '15 at 15:15
  • Oh, on re-reading your question, I see what you mean. The blank node is always bound, so you always get a `[] a mo:Composition` triple. My previous comment doesn't help much. This is an interesting question. Good catch! My initial guess would be that you might be able to use a variable in place of the blank node, and bind it to a blank node in the query. – Joshua Taylor Jan 02 '15 at 15:17
  • @JoshuaTaylor Yep, your first comment explains why optionality for `?performer` and `?singer` works. But what to do about the less trivial case `?composer`?. BINDing the blank node sounds promising (if it's indeed feasible -- I don't know yet how). – Drux Jan 02 '15 at 15:20
  • 1
    I'm not sure offhand, but one thing you might try is putting a variable instead of the literal blank node syntax, and then binding the variable to a blank node with the parameterized sparql string. – Joshua Taylor Jan 02 '15 at 15:23

1 Answers1

1

The following seems to work, when the caller sets composition to a blank node if and only if it sets ?composer to an IRI.

if (composer != null) {
    parameterizedSparqlString.setIri  ("composer"   , composer);
    parameterizedSparqlString.setParam("composition", NodeFactory.createAnon());
}

INSERT {
    ?performance
        mo:performer ?performer ; # optional
        mo:singer    ?singer ;    # optional
        mo:performance_of [
            dc:title ?title ;               # mandatory
            mo:composed_in ?composition ] . # optional
    ?composition a mo:Composition ;
        mo:composer ?composer .
}
WHERE {}

Hats off to @Joshua Taylor for the lead.

I'd still prefer a self-contained version that does not require the additional parameter ?composition (i.e. works without making additional demands on the caller), if that's possible at all.

Drux
  • 11,992
  • 13
  • 66
  • 116
  • "I'd still prefer a self-contained version that does not require the additional parameter ?performer (i.e. works without making additional demands on the caller), if that's possible at all." Can you clarify what you mean by this? Is is that you want the ?performer to be optional as well? If you simply don't provide a binding for ?performer, you should still get the rest of the triples... And to be clear, if you have a value of *either* ?title or ?composition, you'll end up with at least one triple because of the blank node. – Joshua Taylor Jan 02 '15 at 17:32
  • @JoshuaTaylor The SPARQL update is invoked from a Java client. It has natural knowledge about three (of the now four) parameters: `?performer`, `?singer`, `?composer`. Now it has to correctly set a fourth (i,e. `?composition`), which IMHO is a (tiny) bit unfortunate because this spreads the logic for insertion between two places. – Drux Jan 02 '15 at 17:40
  • You wrote *"a self-contained version that does not require the additional parameter **?performer**"* Did you mean *"a self-contained version that does not require the additional parameter **?composition**"*? – Joshua Taylor Jan 02 '15 at 17:55
  • @JoshuaTaylor Typo/sorry. – Drux Jan 02 '15 at 18:21