Appending to a graph from results in a collection

30 views
Skip to first unread message

Douglas Fils

unread,
May 2, 2011, 4:30:50 PM5/2/11
to sca...@googlegroups.com
scardf looks wonderful first off!  I've been wanting something just like this.  I've played with Scala, but I am very new to it..    I got a program tother using both scalaquery and scardf.  

....
  val ts = Vocabulary("http://chronos.org/timecale/1.0/#")

    db withSession {
      for (tt <- Timescale if tt.time_scale_id === 2) {
        val refURL = UriRef("http://chronos.org/timescale/"+ tt._1)
        val gg = Graph(refURL - (ts \ "upper_ma" -> tt._8, ts \ "lower_ma" -> tt._9))
        println(gg.rend)
      }
    }
....

This works just fine... however, here I am simply just making a new graph on each loop and printing it out. 

Is there a way I can use the Augment add type approach to simply just build out (append to) a single graph which at the end I serialize out to a file.n3 or something?

Thanks
Doug

Hrvoje Simic

unread,
May 2, 2011, 5:20:59 PM5/2/11
to sca...@googlegroups.com
Thanks, I'm glad you like it.

Well, augmentation is probably not the way to go since you're building a graph from scratch, not augmenting an existing graph. I guess something like this would be okay (I'm writing this out of the top of my head, so beware of errors):

  val g = Graph(
    for (tt <- Timescale if tt.time_scale_id == 2) yield 
      UriRef("http://chronos.org/timescale/"+ tt._1) -(ts \ "upper_ma" -> tt._8, ts \ "lower_ma" -> tt._9))
  )
  new JenaSerializator( N3 ).write( g, somewhere )

Note that for N3 serialization you need to include Jena. NTriple is implemented in core Scardf.

Cheers,
Hrvoje

Douglas Fils

unread,
May 19, 2011, 1:03:10 PM5/19/11
to sca...@googlegroups.com, hrvoj...@gmail.com
Hrvoje,
  thanks..  sorry the long delay..  I left town on a trip and just got back.  

  I'm still learning the Scala/Functional way..     I did try what you mention with:

 db withSession {
      val mywriter = new FileWriter("/tmp/timescales.n3")
      val g = Graph(
        for (tt <- Timescale if tt.time_scale_id == 2 ) yield
        UriRef("http://chronos.org/timescale/" + tt.age_id) - (ts \ "upper_ma" -> tt.age_max_ma, ts \ "lower_ma" -> tt.age_min_ma))
      new JenaSerializator(N3).write(g, mywriter)
    }

but I get a compiler error with

error: overloaded method value apply with alternatives:
(branches: org.scardf.Branch*)org.scardf.SetGraph <and>
(triples: Set[org.scardf.RdfTriple])org.scardf.SetGraph
cannot be applied to (org.scalaquery.ql.Query[org.scardf.Branch])
val g = Graph(

I don't know if this is something with scala 2.8.1 and scardf 0.5  (do I need scala 2.9?)

Thanks..
Doug


Leif Warner

unread,
May 19, 2011, 2:31:27 PM5/19/11
to scardf
It works just fine with 2.8.1 (haven't tried it on 2.9 yet, myself).
That error's just Scala's way of of saying the Graph() constructor
takes either a parameter list of Branches, or a Set of RdfTriples, but
what it found was a Query of Branches (??)
e.g.
Graph(branch, branch, branch...)
or
Graph(Set(rdftriple, rdftriple, rdftriple...))

There's a diagram of the second form here:
http://code.google.com/p/scardf/wiki/NewModel#Triples_and_graphs

When you make something of the form subjectNode - predicate -> node
that makes a branch.
You can also say RdfTriple(subjectNode, predicate,node) to make a
triple.

I don't have access to your Timescale data structure, but here's
simple examples of both:
Branches:
Graph(
(
for (i <- 1 to 10) yield UriRef(i.toString) - UriRef("knows") ->
UriRef(i * 10 toString)
) : _*
)

(the : _* turns the sequence on yielded branches into the multiple
parameters the Graph constructor was expecting.

or
Triples:
Graph(
(
for (i <- 1 to 10) yield RdfTriple(UriRef(i.toString),
UriRef("knows"), UriRef(i * 10 toString))
) toSet
)

Those are invalid URIs, of course; just for example.
Hope that helps...

-Leif

Leif Warner

unread,
May 19, 2011, 3:51:13 PM5/19/11
to scardf
Oh, and if you do have an existing graph you want to add triples to,
the + operator is defined for that.
e.g. you can say "graph + triple"
(see http://code.google.com/p/scardf/source/browse/trunk/src/main/scala/org/scardf/graph.scala#30)
There's also ++ methods for adding a collection of triples to an
existing graph.
The standard graph is immutable (functional-style), though, so that
won't modify the existing graph, merely return a reference to a graph
with the new triple added.
You could use a fold (the functional equivalent of an accumulating for-
loop) to add lots of triples, or create a graph that you can modify in-
place with like: "val graph = new MutableSetGraph()"

-Leif

Douglas Fils

unread,
May 19, 2011, 4:58:53 PM5/19/11
to sca...@googlegroups.com
Leif,
  It helped a bunch and the more I play with scala and scardf the more I can't wait to play with it more.  :)   I really appreciate all the help with this package.  

  I'm pulling data out of a database with scala query so that is introducing some other boundary conditions.  However, with the help of you both I got this to work.  I'm sure could be doing things more scala / functional like.  

 db withSession {
      val myQuery = for (t <- Timescale if t.time_scale_id === 2) yield t.*
      val myQueryList: List[(Int, Int, Int, Int, String, String, String, String, String, String, String, java.sql.Date, java.sql.Timestamp, String)] = myQuery.list()

      val mywriter = new FileWriter("/tmp/timescales.n3")
      val g = Graph(
        (
          for (tt <- myQueryList) yield RdfTriple(UriRef("http://chronos.org/timescale/" + tt._1), ts \ "upper_ma", Literal(tt._9))
          ) toSet
      )
      new JenaSerializator(N3).write(g, mywriter)
    }


Is there a way in the "yield" to put in more than one triple...  that is I would love to introduce 

RdfTriple(UriRef("http://chronos.org/timescale/" + tt._1), ts \ "lower_ma", Literal(tt._8))

As another object and predicate associated with the same subject URI.  

Thanks again..
Doug



Douglas Fils

unread,
May 19, 2011, 5:03:37 PM5/19/11
to sca...@googlegroups.com
Leif,
  thanks.. this will be useful I know ...    I'm doing several tests related to linked data and ocean science drilling data.  So we may be doing a lot of graph updates and flowing data into things like Virtuoso and SIREn.  It's all the early stages now (our test site is http://data.oceandrilling.org).  

Take care
Doug

Leif Warner

unread,
May 19, 2011, 5:24:49 PM5/19/11
to scardf
Well, I suppose you could yield a List(triple1, triple2, ...) or Set
of triples, which would give you a list of lists at the end, and then
call .flatten on that...

But for that sort of thing (multiple statements about the same
subject) you'd be best of using the Branch construct. So like what
you had written before, only with a : _* at the end of the for-
comprehension being passed into the Graph() constructor. e.g.
Graph( (for ... yield ...) :_* )

An example with numbers:
Graph(
(for (i <- 1 to 10) yield UriRef(i.toString)-(UriRef("likes")-
>UriRef("foo"), UriRef("hates")->UriRef("bar"))) : _*
)

Douglas Fils

unread,
May 19, 2011, 5:51:49 PM5/19/11
to sca...@googlegroups.com
works great...

  val g = Graph (
        (
          for (tt <- myQueryList) yield UriRef("http://chronos.org/timescale/" + tt._1) - (ts \ "upper_ma" -> Literal(tt._9), ts \ "lower_ma" -> Literal(tt._8))
          ) : _*
      )

That really puts me a solid footing to build out graphs..  thanks!

Now on to some SPARQL calls..  I noticed that SPARQL is in the "old api"  is it something I should not use?   From the docs it looks like works on local models only too, ie, no network based SPARQL end points.  

Take care
Doug

Hrvoje Simic

unread,
May 20, 2011, 10:05:28 AM5/20/11
to sca...@googlegroups.com
On Thu, May 19, 2011 at 23:51, Douglas Fils <drf...@gmail.com> wrote:
> Now on to some SPARQL calls..  I noticed that SPARQL is in the "old api"  is it something I should not use?   From the docs it looks like works on local models only too, ie, no network based SPARQL end points.

You can use SPARQL methods on the "new API" too.

"net.croz.scardf.query" package is a part of "the old API", and as
such it is not recommended. It still works as well as it ever did, of
course, but it's not compatible with the new model and it probably
won't be developed further. It was an experiment in Scala DSL, aiming
to provide a typesafe imitation of the actual SPARQL syntax. Since the
SPARQL is a quite complex language, this goal was only partially
achieved:

http://code.google.com/p/scardf/wiki/Querying

After the redesign, this functionality was not ported. What remains is
the org.scardf.QueryEngine trait, which is implemented by
org.scardf.jena.JenaGraph. A SPARQL expression is here given as a
string.

Remote endpoints are not supported directly, but also through Jena, e.g.

http://stackoverflow.com/questions/3493238/how-do-i-query-update-a-remote-rdf-endpoint-with-jena

Note that I haven't tried it myself, though.

Hrvoje

Leif Warner

unread,
May 22, 2011, 2:33:49 PM5/22/11
to scardf
The old API only built on Scala 2.7, if I recall... I remember adding
support for querying remote endpoints to the SPARQL DSL using the
underlying Jena:

https://github.com/LeifW/scardf/commit/f8cf3c3e5b7888c97d2c94a061099bfb5f617cfa

Looks like you just give it a string representing the URI of the
remote endpoint rather than a model object to query against, and it
works the same.

Here's SPARQL query methods on the JenaGraph class:

http://code.google.com/p/scardf/source/browse/trunk/src/main/scala/org/scardf/jena/jena-graph.scala#80

Just pass in a SPARQL query string. It would hardly be any work at
all to re-use the wrapping to Scala types provided by this layer on
remote endpoint queries, too.

-Leif
>  http://stackoverflow.com/questions/3493238/how-do-i-query-update-a-re...

Leif Warner

unread,
May 23, 2011, 4:53:55 PM5/23/11
to sca...@googlegroups.com
Given that the existing syntax for local graphs is along the lines of:

val graph = JenaGraph....
graph select "SELECT * WHERE {?s ?p ?o}"  
( syntax sugar for graph.select("SELECT...") )

for querying remote services, we could throw in something like:

SparqlService("http://dbpedia.org/sparql") select "SELECT * WHERE {?s ?p ?o}"

or even, using implicit conversions:

"http://dbpedia.org/sparql" select "SELECT * WHERE {?s ?p ?o}"

?
Reply all
Reply to author
Forward
0 new messages