drlivingston / kr

Clojure API for RDF and SPARQL - provides consistent access to APIs including Jena and Sesame
56 stars 17 forks source link

construct query #4

Open ouvanous opened 11 years ago

ouvanous commented 11 years ago

Hi,

Is it possible to do a CONSTRUCT sparql query ? Thanks, Sam

drlivingston commented 11 years ago

Hi Sam,

Thanks for you question.

With the code as it currently stands you have two choices. The most straight forward (but maybe least satisfying) is to use the the edu.ucdenver.ccp.kr.sparql/sparql-query function to pass in sparql strings directly to the KB instead of the query function that uses patterns. You could use the other functions in edu.ucdenver.ccp.kr.sparql to help you construct the sparql strings. sparql-query-body will get you 90% of the way there.

https://github.com/drlivingston/kr/blob/master/kr-core/src/main/clojure/edu/ucdenver/ccp/kr/sparql.clj

(although I'm realizing there might be problems with the return type - as the output is triples not bindings...)

The other immediately available option is to use a forward-chaining rule -- which are essentially constructs with a few more (optional) bells and whistles and they are formatted as clj data so they can be more easily tested and manipulated. Take a look at edu.ucdenver.ccp.kr.forward-rule/run-forward-rule

https://github.com/drlivingston/kr/blob/master/kr-core/src/main/clojure/edu/ucdenver/ccp/kr/forward_rule.clj

There are some examples of the rules and their tests here:

https://github.com/drlivingston/kr/blob/master/kr-core/src/test/clojure/edu/ucdenver/ccp/test/kr/test_forward_rule.clj

The rules are meant to be declarative date, and serialized in any number of actionable ways. Right now there is just this rule applier, but they could also be made into CONSTRUCTS or I have another pending request to look at outputting them in RIF.


That said, it shouldn't be hard to create a function edu.ucdenver.ccp.kr.sparql/construct that would take two triple patterns and then generate the correct sparql string. As far as I can tell from looking at the docs for construct only triple patterns seem to be allowed so this should actually be very straight-forward. I'll try to put something together soon, and put in a patch. (feedback always welcome too)

The trickier bit will probably be extending the sparqlKB protocol to have a construct function and getting the return types correct. The results of a construct query is a full graph / rdf document right? but it's not immediately materialized into the KB, right? What are the typical use-cases for the output of constructs?

thanks, Kevin

drlivingston commented 11 years ago

I've added API support for sparql construct queries, in both the return a set of statements form and a visitor form. I implemented a Sesame version of this. (I don't know if you are using the sesame or jena implementation) Jena shouldn't be too hard to add.

If you want to test this against your use cases you can grab a copy of the current repository from github then in the top kr directory:

mvn clean package install

then use as coordinates for KR in your project the version 1.4.9-SNAPSHOT

You can see example calls here (they work just like query):

https://github.com/drlivingston/kr/blob/master/kr-core/src/test/clojure/edu/ucdenver/ccp/test/kr/test_sparql_construct.clj

Kevin

drlivingston commented 11 years ago

I should have added like the query calls there are also equivalent sparql forms too, so you can pass in a sparql string and get back clj-ify'ed results.

Kevin

drlivingston commented 11 years ago

I'm pushing version 1.4.9 public now. It has support for construct and construct-visit for both the Sesame and Jena implementations.

Hopefully this addresses your use case - please let me know, and I'll close this issue. Or if not we can add some more tests, or ways to interact with it.

Kevin

ouvanous commented 11 years ago

Hi Kevin I am terribly sorry because i tought i respond to you sooner but apparently my response is not here (don't know what was wrong ?).

So first thanks for your quick addition ! What i need was to have a turtle representation of a SPARQL contruct query.

So i used something like that :

(defn get-turtle-construct [kb](let [con %28:connection kb%29 query %28.prepareGraphQuery con org.openrdf.query.QueryLanguage/SPARQL %28construct-query kb%29%29 bs %28java.io.ByteArrayOutputStream. %29 writer %28org.openrdf.rio.turtle.TurtleWriter. bs%29 result %28.evaluate query writer%29 ] %28.toString bs)))

This work perfectly for me. I will have a look at what you've done.

Thanks again for your wrok and sorry for this late response.

Samuel

drlivingston commented 11 years ago

Ah. OK. I thought about implementing the writing to files too... as an intermediary you could use the visit pattern and set up a writer KB to add the triples to the output KB. That will get you an ntriple file. That's a little round-about but it would work fine. The example writer KB uses NTtriple by default (that's all I initially needed) but it shouldn't be hard to create a flag to change which RDF writer is used.

see the sesame-writer-kb

https://github.com/drlivingston/kr/blob/master/kr-sesame/kr-sesame-core/src/main/clojure/edu/ucdenver/ccp/kr/sesame/writer_kb.clj

Kevin

(I think it's a worthwhile patch - and should be done, I might not be able to code this up in under a week though - I'm at professional meetings and other obligations this week.)