Graph Guide

scala>  import lspace._
import lspace._

scala>  import lspace.Implicits.Scheduler.global
import lspace.Implicits.Scheduler.global

scala>  import lspace.Implicits.SyncGuide.guide
import lspace.Implicits.SyncGuide.guide

scala>  import lspace.provider.mem.MemGraph
import lspace.provider.mem.MemGraph

scala>  import lspace.structure._
import lspace.structure._

scala>  import Label.D._
import Label.D._

scala>  import lspace.util.SampleGraph
import lspace.util.SampleGraph

What is a graph

A graph is a collection of nodes, unordered edges and values, these are all resources. Nodes can be labelled and nodes can have edges. Edges have a source (‘from’) and a destination (‘to’) resource which can both be either a node, edge or value. The edge is always labeled with a key (property) and an edge can also be the source to other edges (statements on edges). Values have a data-value and values can have edges.

  • Graphs support Librarian-traversals
  • Graphs can be merged (graph ++ graph)
  • Graphs support transactions (graph.transaction -> new in-memory graph with ‘commit’ function)
  • Graph support history (never delete, only add an edge (@deletedon) to the edge .. to be tested)

create a graph

scala>  val graph: Graph = MemGraph("graph-doc")
graph: lspace.structure.Graph = graph:graph-doc

scala>  import scala.concurrent.duration._
import scala.concurrent.duration._

scala>  scala.concurrent.Await.ready(lspace.util.SampleGraph.loadSocial(graph).runToFuture, 5.seconds)
res0: monix.execution.CancelableFuture[AnyRef{val places: AnyRef{val SanJosédeMaipo: AnyRef{val place: lspace.structure.Node; val id: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultString.C]; val name: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultString.C]; val geo: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultGeopoint.C]}; val CrystalSprings: AnyRef{val place: lspace.structure.Node; val id: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultString.C]; val name: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultString.C]; val geo: lspace.structure.Edge[lspace.structure.Node,lspace.structure.ut...

scala>  val labels = SampleGraph.ontologies
labels: lspace.util.SampleGraph.ontologies.type = lspace.util.SampleGraph$ontologies$@7c56c89d

scala>  val keys = SampleGraph.properties
keys: lspace.util.SampleGraph.properties.type = lspace.util.SampleGraph$properties$@4daf9672

How to use

First steps:

import lspace._ //easy access to common object (types)
import lspace.Implicits.Scheduler.global //default scheduler (execution context)
import lspace.Implicits.SyncGuide.guide //graph-engine
//import lspace.Implicits.AsyncGuide.guide //async execution of traversals
//import lspace.Implicits.RemoteGuide.guide //async remote execution of traversals (w.i.p.)

To create a graph (in-memory):

val graph = Graph("my-graph-url")

A graph always has a name, ideally this would be a url so it can be referenced.

Before continuing reading and learning, first load some sample-data:

lspace.util.SampleGraph.loadSocial(graph).runToFuture

Graphs have a some basis API’s which allows for reading from and writing to the graph.

Resource API’s

Graph-resources can all be retrieved by Iri (@id) or by Id. Values and edges do mostly not have an Iri (empty-string). There are API’s on each structure-level (resource, value, edge and node).

The main methods per section:

Resources API

hasIri

graph.resources.hasIri("graph-doc/place/123")
// res1: monix.reactive.Observable[lspace.structure.Resource[Any]] = monix.reactive.internal.operators.ConcatMapObservable@feb8fb0

graph.resources.hasIri("graph-doc/place/123", "graph-doc/person/123")
// res2: monix.reactive.Observable[lspace.structure.Resource[Any]] = monix.reactive.internal.operators.ConcatMapObservable@7c817c41

hasId

graph.resources.hasId(1001L).id
// res3: monix.eval.Task[Option[Long]] = Task.Map$871942149

upsert

graph.values.create("some-literal")
// res4: monix.eval.Task[lspace.structure.Value[String]] = Task.FlatMap$1348135312

graph.values.create("some-literal") //should be equal because values are deduplicated
// res5: monix.eval.Task[lspace.structure.Value[String]] = Task.FlatMap$1203519352

graph.values.create("some-literal2") //new value, hence new id
// res6: monix.eval.Task[lspace.structure.Value[String]] = Task.FlatMap$673282489

count:

graph.resources.count()
// res7: monix.eval.Task[Long] = Task.Map$1539280785

Resource

A resource ..

Nodes API

Nodes can be:

Retrieved by Iri(s)/Uri(s):

graph.nodes.hasIri("graph-doc/place/123")
// res8: monix.reactive.Observable[lspace.structure.Node] = monix.reactive.internal.operators.ConcatMapObservable@4c85e086

graph.nodes.hasIri("graph-doc/place/123", "graph-doc/person/123")
// res9: monix.reactive.Observable[lspace.structure.Node] = monix.reactive.internal.operators.ConcatMapObservable@222935b

Retrieved by Id(s):

graph.nodes.hasId(1002L)
// res10: monix.eval.Task[Option[lspace.structure.Node]] = Task.Eval$1866646310

Counted:

graph.nodes.count()
// res11: monix.eval.Task[Long] = Task.Eval$637628586

Node

A node ..

Edges API

Edges can be:

Counted:

graph.edges.count()
// res12: monix.eval.Task[Long] = Task.Eval$204040845

Edge

An edge ..

Values API

Counted:

graph.values.count()
// res13: monix.eval.Task[Long] = Task.Eval$1979573048

Value

A value ..

History

A graph can have a history trait which means that resources are time aware and annotated with supporting “@createdon” and “@deletedon” tags.