On Mon, Feb 25, 2013 at 4:58 PM, Joshua TAYLOR <[email protected]> wrote:
> On Mon, Feb 25, 2013 at 4:32 PM, Andy Seaborne <[email protected]> wrote:
>> On 25/02/13 20:14, Joshua TAYLOR wrote:
>>>
>>> On Mon, Feb 25, 2013 at 2:15 PM, Joshua TAYLOR <[email protected]>
>>> wrote:
>>>>
>>>> On Mon, Feb 25, 2013 at 1:43 PM, Joshua TAYLOR <[email protected]>
>>>> wrote:
>>>>>
>>>>> On Mon, Feb 25, 2013 at 11:42 AM, Joshua TAYLOR <[email protected]>
>>>>> wrote:
>>>>>>
>>>>>> I'm looking at upgrading a project to use the new 2.10.0 release, and
>>>>>> things are coming along nicely so far (some possible hitches in some
>>>>>> writing code, but can't run tests until I can build...). I've got a
>>>>>> bunch of cases of
>>>>>>
>>>>>> UpdateAction.execute(request, getModel(), binding);
>>>>>>
>>>>>> that don't compile, though; according to the release notes [1],
>>>>>> "SPARQL Update execution no longer supports setting an initial
>>>>>> binding". I'm going to keep looking for the new way to do this, but
>>>>>> in case someone's got the quick answer prepared, and so that the list
>>>>>> has a recorded answer, I figured I'd ask sooner rather than later:
>>>>>> how can initial bindings be specified in Jena 2.10.0?
>>>>>>
>>>>>> [1]
>>>>>> http://svn.apache.org/repos/asf/jena/trunk/jena-arq/ReleaseNotes.txt
>>>>>
>>>>>
>>>>> After some lunch, and some searching, I've found discussion on the dev
>>>>> list about removing initial bindings [1] and that the accepted way to
>>>>> do this now is to use BIND or VALUES. In our project, we've
>>>>> implemented a number of EnhancedResources that perform graph updates
>>>>> using an idiom where some SPARQL text refers to a ?this variable, and
>>>>> the execution uses a binding that binds ?this to the enhanced resource
>>>>> (which might not have a URI). We'd much prefer to do the graph
>>>>> modification via SPARQL because it involves a number of operations,
>>>>> and we'd like to be able to use anonymous resources. Here's a typical
>>>>> example:
>>>>>
>>>>> static private final UpdateRequest setSomePropertyRequest =
>>>>> UpdateFactory.create(
>>>>> "DELETE {\n"+
>>>>> .... SPARQL code that uses variable ?this ...
>>>>> "} INSERT {\n"+
>>>>> "} WHERE {"+
>>>>> ...
>>>>> "}"
>>>>> );
>>>>>
>>>>> public Invocation setSomeProperty( Value value ) {
>>>>> final QuerySolutionMap binding = new
>>>>> QuerySolutionMap();
>>>>> binding.add("?this", this );
>>>>> UpdateAction.execute( setSomePropertyRequest,
>>>>> getModel(), binding);
>>>>> }
>>>>> return this;
>>>>> }
>>>>>
>>>>> Is there still a way to do something like this? If it will involve
>>>>> using VALUES or BIND, is there a way to make it work with blank nodes?
>>>>>
>>>>> Thanks in advance,
>>>>> //JT
>>>>>
>>>>> [1]
>>>>> http://mail-archives.apache.org/mod_mbox/jena-dev/201302.mbox/%3CCAPTxtVNWT1HncCLom14cTF0WcjJ04pyP8ALes5Vb5yuSDv8DWw%40mail.gmail.com%3E
>>>>
>>>>
>>>> Sorry for so much noise, but I wonder if the following is a solution.
>>>> This does depend, of course, on the model against which the update is
>>>> run being on the same machine, and such. If "this" has a URI, then I
>>>> can use the URI in the query, and if it's anonymous, then I can use
>>>> the Jena-specific-and-depending-on-local-data id. Then I can use
>>>> request.add( "BIND ( ... as ?this )" ) to add the binding constraints
>>>> to the request.
>>>>
>>>> final UpdateRequest request =
>>>> UpdateFactory.create(); // ... more
>>>> query in real example
>>>> if ( this.isAnon() ) {
>>>> request.add( "BIND (
>>>> <_:"+this.getId()+"> as ?thisInvocation )" );
>>>> }
>>>> else {
>>>> request.add( "BIND (
>>>> <_:"+this.getURI()+"> as ?thisInvocation )" );
>>>> }
>>>> UpdateAction.execute( request, model ); //
>>>> executes with the
>>>> requested binding
>>>>
>>>> If this is a solution, it's easy enough to wrap cleanly in a util
>>>> method, and I'll be content with that. Can anyone confirm or deny
>>>> that this is a solution? (I'm hoping that I understand the
>>>> UpdateRequest#add( String ) method correctly. The javadoc [1] is
>>>> empty, so I'm going on a guess...)
>>>>
>>>> //JT
>>>>
>>>> [1]
>>>> http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/update/UpdateRequest.html#add(java.lang.String)
>>>
>>>
>>> Sorry for all the noise and self-replies, but this doesn't work.
>>> UpdateRequest#add doesn't do what I hoped it did. Again, the issue
>>> is, what do we do instead of initial bindings in Jena 2.10.0. We've
>>> been using a bunch of precompiled update requests, and had been able
>>> to provide initial bindings for them. I understand that we should now
>>> be using BIND to introduce bindings, but this will still require some
>>> sort of parameterization (which we did before using initial
>>> bindings). Thoughts?
>>
>>
>> What about
>>
>> ParameterizedSparqlString
>> .asUpdate()
>
> This may very well be the answer. One of the reasons that we'd been
> using UpdateRequests was a (hopefully not too mistaken?) attempt at
> "pre-compiling" the queries. If we move to parameterized SPARQL
> strings, it seems like we'll be imposing a fair amount of overhead,
> since "this class does not in any way check that your command is
> syntactically correct until such time as you try and parse it as a
> Query or UpdateRequest" [1]. Then again, maybe the parsing is much
> quicker than running a query with initial bindings? I haven't run
> tests yet to compare this.
>
> As an aside, the docs for ParameterizedSPARQLString state "The
> intended usage of this is where using a QuerySolutionMap as initial
> bindings is either inappropriate or not possible." If one is doing
> updates, are there any APIs that still support initial bindings?
>
>> The technical problem with initial bindings and SPARQL update is what do
>> they apply to - your examples are one SPARQL Update operation; in general, a
>> SPARQL Update request may be several operations.
>
> (I missed this part of your message at first reading; some email
> clients (e.g., GMail) treat everything below the double hyphen as a
> signature.) Ah, thanks. I haven't done much SPARQL querying/updating
> in Jena in a while, and I'm coming into code that someone else wrote.
> I can see where this is a pretty useful way of combining remote
> queries.
>
> For the moment, I'll change things to use parameterized SPARQL
> strings. Hopefully the much more frequent parsing won't be an issue
> (we're executing some of these queries very frequently, and always
> against local models). If I run into problems, you can be sure I'll
> be back!
>
> As always, many thanks for the help, and a great platform,
> [1]
> http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/ParameterizedSparqlString.html
This is pretty close, but there's still a problem. When a blanknode
is substituted into a ParameterizedSparqlString, it's replaced by
something like "_:b0" rather than the pseudo-form <_:blank-node-id>.
That's easy enough to get around; I can use setIri and construct the
blank node's iri from "_:"+node.getId(). This means that I can get a
ParameterizedSparqlString that looks like the update that I want.
However, asUpdate() turns those pseudo-iris back into the blank nodes
like "_:b0". Here's an example of this (code is set up as a JUnit
test):
public class ParameterizedSparqlStrings {
@Test
public void showResults() {
OntModel model = ModelFactory.createOntologyModel(
OntModelSpec.OWL_DL_MEM );
Individual a = model.createIndividual( OWL.Thing );
Individual b = model.createIndividual(
"http://example.org/individual", OWL.Thing );
String sparqlString = "INSERT {\n"+
" ?aByNode a ?ignore . \n"+
" ?aByIri a ?ignore . \n"+
" ?bByNode a ?ignore . \n"+
" ?bByIri a ?ignore . \n"+
"} WHERE {}";
ParameterizedSparqlString pss = new ParameterizedSparqlString(
sparqlString );
pss.setParam( "?aByNode", a );
pss.setIri( "?aByIri", "_:"+a.getId() );
pss.setParam( "?bByNode", b );
pss.setIri( "?bByIri", b.getURI() );
System.out.println( "\n* Parameterized Sparql String with
Ids:\n" + pss );
System.out.println( "\n* Parameterized Sparql String as
Update:\n" +
pss.asUpdate() );
}
}
and here's the output: (In the parameterized string, ?aByIRI is what
I'd like to have for the update, but it gets clobbered by asUpdate().)
* Parameterized Sparql String with Ids:
INSERT {
_:b0 a ?ignore .
<_:-570c0f1c:13d1389a5a3:-7ffc> a ?ignore .
<http://example.org/individual> a ?ignore .
<http://example.org/individual> a ?ignore .
} WHERE {}
* Parameterized Sparql String as Update:
INSERT {
_:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
<http://example.org/individual>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
<http://example.org/individual>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
}
WHERE
{ }
Thoughts?
//JT
--
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/