Traversal Guide
- Overview
- The traverser
- The traversal
- Steps
Overview
To acquire knowledge, one must be able to communicate with the Librarian. This document should provide guidance in reasoning on a graph.
The traverser
When a librarian is sent on his way to gather knowledge as instructed with a traversal, the librarian (aka traverser) moves through L-space (aka graph(s)) and keeps track of his whereabouts and the encountered resources. When he reaches the end of the traversal he communicates back the result that was requested.
The traversal
A traversal is an ADT structure which can be compared, concatenated, serialized/deserialized etc.
A traversal exists of steps which are grouped into segments (rules on segmentation: …).
A segments starts with a move or transform step (new librarian with new information).
To make a traversal ready for execution add .withGraph(graph)
after the execution. This action will analyse the traversal,
depending on the nature of the traversal, guide and the result-type the user can do one of the following monadic operations:
.headF
.headOptionF
.lastF
.lastOptionF
.toListF
.toSetF
.toMapF
this one is only available when there is a Group-step at the root of all container-typed steps
when synchronous operations are available each of these methods has a synchronous counterpart without the ‘F’-suffix
Steps
The librarian is able to execute the following steps.
Resource steps
Resource-step to start specify what type of resources the traversal should start in.
Graph
Graph-selection step to point the librarian to a specific part of the L-space (we would not want to defy the large quantity of knowledge from the whole multiverse has to offer).
val graph: Graph = MemGraph("librarian-doc")
// graph: Graph = graph:librarian-doc
import scala.concurrent.duration._
scala.concurrent.Await.ready(lspace.util.SampleGraph.loadSocial(graph).runToFuture, 5.seconds)
// res0: monix.execution.CancelableFuture[{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.util.ClassTypeable.defaultGeopoint.C]}; val Haridwar: 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 Talca: 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 persons: AnyRef{val Yoshio: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val balance: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultDouble.C]; val rate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}; val Levi: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val balance: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultDouble.C]; val rate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}; val Gray: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val balance: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultDouble.C]; val rate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}; val Kevin: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val balance: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultDouble.C]; val rate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}; val Stan: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val balance: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val rate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultInt.C]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}; val Garrison: AnyRef{val person: 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 birthdate: lspace.structure.Edge[lspace.structure.Node,lspace.structure.util.ClassTypeable.defaultLocalDate.C]; val birthPlace: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]; val address: lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]}};val knows: AnyRef{val GarrissonKnownStan: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]); val GarrissonKnownKevin: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]); val KevinKnownStan: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]); val KevinKnownGray: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]); val GrayKnowsLevi: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node]); val LeviKnowsYoshio: (lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node], lspace.structure.Edge[lspace.structure.Node,lspace.structure.Node])}}] = Async(
// underlying = Future(Success(lspace.util.SampleGraph$$anon$15@2e6b5b5e)),
// cancelable = monix.eval.internal.TaskConnection$Impl$$anon$1@48933671,
// isolatedCtx = null
// )
val labels = SampleGraph.ontologies
// labels: SampleGraph.ontologies.type = lspace.util.SampleGraph$ontologies$@16c845a7
val keys = SampleGraph.properties
// keys: SampleGraph.properties.type = lspace.util.SampleGraph$properties$@4f613e75
N
N-step is a node selection step
E
E-step is an edge selection step
V
V-step is a value selection step
R
R-step is a resource (node, edge and value) selection step
Filter steps
A filter determines if the traverser should continue with the traversal or not.
Has steps
Has
Has-step validates the presence of a property and optionally asserts it by one or more predicates
g.N.has("name").out("name").withGraph(graph).toList //filters on nodes which have an edge with property "name"
// res1: List[Any] = List(
// "Stan",
// "Haridwar",
// "Garrison",
// "Crystal Springs",
// "Gray",
// "Talca",
// "Kevin",
// "Levi",
// "Yoshio",
// "San Jos\u00e9 de Maipo"
// ) //filters on nodes which have an edge with property "name"
g.N.has("name", P.eqv("Garrison")).out("name").withGraph(graph).toList //adds an equality constraint with value "Alice"
// res2: List[Any] = List("Garrison") //adds an equality constraint with value "Alice"
g.N.has(keys.birthDate, P.gt(LocalDate.parse("2002-06-13"))).id.withGraph(graph).toList
// res3: List[Long] = List(1268L, 1206L)
HasNot
HasNot-step is the inverse of a Has-step (this could also be written as .not(_.has(..))
)
HasLabel
HasLabel-step validates the precence of one or more labels (ontology, property or datatype)
g.N.hasLabel(labels.person).out(keys.name).withGraph(graph).toList //filters all persons
// res4: List[Any] = List(
// "Stan",
// "Garrison",
// "Gray",
// "Kevin",
// "Levi",
// "Yoshio"
// ) //filters all persons
g.N.hasLabel(labels.place).out(keys.name).withGraph(graph).toList //filters all places
// res5: List[Any] = List(
// "Haridwar",
// "Crystal Springs",
// "Talca",
// "San Jos\u00e9 de Maipo"
// )
HasId
HasId-step validates if the id is within a certain set.
g.N.hasId(1001l).out(keys.name).withGraph(graph).toList
// res6: List[Any] = List()
HasIri
HasIri-step validates if the iri is within a certain set.
g.N.hasIri("graph-doc/place/123").out(keys.name).withGraph(graph).toList
// res7: List[Any] = List()
Global Filter steps
Dedup
Dedup-step filters traversers with distinct values
g.N.limit(1).union(_.out().limit(1), _.out().limit(1)).count.withGraph(graph).head //shouldBe 2
// res8: Long = 2L //shouldBe 2
g.N.limit(1).union(_.out().limit(1), _.out().limit(1)).dedup().count.withGraph(graph).head //shouldBe 1
// res9: Long = 1L
Coin
Coin-step filters traversers on a coin-flip result for probability p
g.N.count.withGraph(graph).head //total nodes to draw from
// res10: Long = 11L //total nodes to draw from
g.N.coin(0.2).id.withGraph(graph).toList //random selection of nodes with p = 0.2 (20%)
// res11: List[Long] = List(1304L, 1017L) //random selection of nodes with p = 0.2 (20%)
g.N.coin(0.8).id.withGraph(graph).toList //random selection of nodes with p = 0.8 (80%)
// res12: List[Long] = List(
// 1286L,
// 1095L,
// 1304L,
// 1054L,
// 1247L,
// 1001L,
// 1268L,
// 1206L,
// 1144L,
// 1017L
// )
Where
Where-step takes a traversal and filters on non-empty results
g.N.where(_.has("name")).out("name").withGraph(graph).toList
// res13: List[Any] = List(
// "Stan",
// "Haridwar",
// "Garrison",
// "Crystal Springs",
// "Gray",
// "Talca",
// "Kevin",
// "Levi",
// "Yoshio",
// "San Jos\u00e9 de Maipo"
// )
And
And-step takes one or more traversals and filters only those which have non-empty results for all traversals
g.N.and(_.has("name"), _.has("https://example.org/birthDate")).out(keys.name, keys.birthDate).withGraph(graph).toList
// res14: List[Any] = List(
// "Stan",
// 2002-06-13,
// "Garrison",
// 1994-06-18,
// "Gray",
// 1997-04-10,
// "Kevin",
// 2008-11-30,
// "Levi",
// 2008-12-20,
// 1996-08-18,
// "Yoshio"
// )
g.N.and(_.has(keys.balance, P.gt(300)), _.has(keys.balance, P.lt(3000))).count.withGraph(graph).head //shouldBe 2
// res15: Long = 2L
Or
Or-step takes one or more traversals and filters only those which have non-empty results for at least one traversal
g.N.or(_.has("name"), _.has("https://example.org/birthDate")).out(keys.name, keys.birthDate).withGraph(graph).toList
// res16: List[Any] = List(
// "Stan",
// 2002-06-13,
// "Haridwar",
// "Garrison",
// 1994-06-18,
// "Crystal Springs",
// "Gray",
// 1997-04-10,
// "Talca",
// "Kevin",
// 2008-11-30,
// "Levi",
// 2008-12-20,
// 1996-08-18,
// "Yoshio",
// "San Jos\u00e9 de Maipo"
// )
Not
Not-step takes a traversal and filters on empty results
g.N.not(_.has("name")).limit(2).id.withGraph(graph).toList
// res17: List[Long] = List(1001L)
Is
Is-step asserts a value against one or more predicates
g.N.out().is(P.eqv(300)).out(keys.name).withGraph(graph).toList //filters the all outgoing resources with value 2
// res18: List[Any] = List()
Clip steps
A clip step cuts the resulting stream of traversers.
Range
Range-step filters by a low-end and high-end index
g.N.range(4, 16).iri.withGraph(graph).toList //takes only node 4 until 16
// res19: List[String] = List(
// "librarian-doc/place/12345",
// "librarian-doc/person/345",
// "librarian-doc/place/34567",
// "librarian-doc/person/34567",
// "librarian-doc/person/12345",
// "librarian-doc/person/123",
// "librarian-doc/place/123"
// )
Limit
Limit-step takes the first x-number of traversers
g.N.limit(12).iri.withGraph(graph).toList //takes only the first 12 nodes
// res20: List[String] = List(
// "librarian-doc/person/567",
// "librarian-doc/place/345",
// "librarian-doc/person/56789",
// "librarian-doc/place/12345",
// "librarian-doc/person/345",
// "librarian-doc/place/34567",
// "librarian-doc/person/34567",
// "librarian-doc/person/12345",
// "librarian-doc/person/123",
// "librarian-doc/place/123"
// )
Skip
Skip-step ignores the first x-number of traversers
g.N.skip(12).iri.withGraph(graph).toList //ignores the first 12 nodes
// res21: List[String] = List()
Tail
Tail-step takes the last x-number of traversers
g.N.tail(12).iri.withGraph(graph).toList //takes only the last 12 nodes
// res22: List[String] = List(
// "librarian-doc/person/567",
// "librarian-doc/place/345",
// "librarian-doc/person/56789",
// "librarian-doc/place/12345",
// "librarian-doc/person/345",
// "librarian-doc/place/34567",
// "librarian-doc/person/34567",
// "librarian-doc/person/12345",
// "librarian-doc/person/123",
// "librarian-doc/place/123"
// )
Move steps
Move steps lets the traverser move through the graph. The path can be stored within the traverer
Out
Out-step takes one or more property-labels and traverses along the valid outgoing paths if any
g.N.out("name").withGraph(graph).toList
// res23: List[Any] = List(
// "Stan",
// "Haridwar",
// "Garrison",
// "Crystal Springs",
// "Gray",
// "Talca",
// "Kevin",
// "Levi",
// "Yoshio",
// "San Jos\u00e9 de Maipo"
// )
OutE
OutE-step takes one or more property-labels and traverses to the valid outgoing paths if any
g.N.outE("name").withGraph(graph).toList
// res24: List[Edge[Node, Any]] = List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e50d,
// lspace.provider.mem.MemGraph$$anon$8@5db0e45e,
// lspace.provider.mem.MemGraph$$anon$8@5db0e51f,
// lspace.provider.mem.MemGraph$$anon$8@5db0e433,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4ed,
// lspace.provider.mem.MemGraph$$anon$8@5db0e470,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4fb,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4cb,
// lspace.provider.mem.MemGraph$$anon$8@5db0e48a,
// lspace.provider.mem.MemGraph$$anon$8@5db0e419
// )
In
In-step takes one or more property-labels and traverses along the valid incoming paths if any
g.N.out("name").withGraph(graph).toList
// res25: List[Any] = List(
// "Stan",
// "Haridwar",
// "Garrison",
// "Crystal Springs",
// "Gray",
// "Talca",
// "Kevin",
// "Levi",
// "Yoshio",
// "San Jos\u00e9 de Maipo"
// )
InE
InE-step takes one or more property-labels and traverses to the valid incoming paths if any
g.N.outE("name").withGraph(graph).toList
// res26: List[Edge[Node, Any]] = List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e50d,
// lspace.provider.mem.MemGraph$$anon$8@5db0e45e,
// lspace.provider.mem.MemGraph$$anon$8@5db0e51f,
// lspace.provider.mem.MemGraph$$anon$8@5db0e433,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4ed,
// lspace.provider.mem.MemGraph$$anon$8@5db0e470,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4fb,
// lspace.provider.mem.MemGraph$$anon$8@5db0e4cb,
// lspace.provider.mem.MemGraph$$anon$8@5db0e48a,
// lspace.provider.mem.MemGraph$$anon$8@5db0e419
// )
Label
Label-step traverses to the label-nodes if any
g.N.label().withGraph(graph).toList
// res27: List[Ontology] = List(
// ontology:https://example.org/Person,
// ontology:https://example.org/Place,
// ontology:https://example.org/Person,
// ontology:https://example.org/Place,
// ontology:https://example.org/Person,
// ontology:https://example.org/Place,
// ontology:https://example.org/Address,
// ontology:https://example.org/Person,
// ontology:https://example.org/Person,
// ontology:https://example.org/Person,
// ontology:https://example.org/Place
// )
Branche steps
Branche steps can execute one or more separate traversals, execute those in a specific way and merges any results back into the original traversal
Union
Union-step takes one or more traversals and merges the results into a single traversal
g.N.union(_.out(), _.in()).withGraph(graph).toList //all incoming and outgoing edges
// res28: List[Any] = List(
// 2002-06-13,
// 300,
// 4,
// "librarian-doc/person/567",
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// "Stan",
// lspace.provider.mem.MemGraph$$anon$7@5db0e3fc,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// "librarian-doc/place/345",
// Point(x = 89.45136, y = 88.01204),
// "Haridwar",
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// 1994-06-18,
// "librarian-doc/person/56789",
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// "Garrison",
// lspace.provider.mem.MemGraph$$anon$7@5db0e46a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// "librarian-doc/place/12345",
// Point(x = -48.4046, y = 175.87173),
// "Crystal Springs",
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// 1997-04-10,
// 2230.3,
// 1,
// "librarian-doc/person/345",
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// "Gray",
// lspace.provider.mem.MemGraph$$anon$7@5db0e44a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// "librarian-doc/place/34567",
// Point(x = 74.32746, y = -45.06438),
// "Talca",
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// "888",
// "apples",
// 1,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// ... //all incoming and outgoing edges
g.N.union(_.has(keys.balance, P.gt(300)), _.has(keys.balance, P.lt(-200))).count.withGraph(graph).head //should be 3
// res29: Long = 3L
Local
Local-step takes a traversal and performs any barrier, environment or other more global operations only over the results upto the traverser at the root the local-traversal
g.N.local(_.out().hasLabel[Int].sum).withGraph(graph).toList //sums all outgoing edges to integers for each node in the graph
// res30: List[Double] = List(
// 304.0,
// 0.0,
// 0.0,
// 0.0,
// 1.0,
// 0.0,
// 1.0,
// 2.0,
// 2.0,
// 4.0,
// 0.0
// )
Repeat
Repeat-step takes a traversal and keeps repeating it until a certain requirement is met, a maximum number of repeats is reached or the traversal is exhausted. A repeat step returns only the result of the last repeat iteration but can also return the result of each intermediary iteration by providing ‘collect = true’.
g.N.repeat(_.out("knows")).withGraph(graph).toList //repeats as long as there are outgoing "knows" edges (can easily contain infinite loops)
// res31: List[Any] = List() //repeats as long as there are outgoing "knows" edges (can easily contain infinite loops)
g.N.repeat(_.out("knows"))(_.hasLabel(Ontology("Officer"))).withGraph(graph).toList //repeats as long as there are outgoing "knows" edges and the result is not of type "Officer"
// res32: List[Any] = List() //repeats as long as there are outgoing "knows" edges and the result is not of type "Officer"
g.N.repeat(_.out("knows"), 3)(_.hasLabel(Ontology("Officer"))).withGraph(graph).toList //repeats three times at most if there are outgoing "knows" edges and the result is not of type "Officer"
// res33: List[Any] = List() //repeats three times at most if there are outgoing "knows" edges and the result is not of type "Officer"
g.N.repeat(_.out("knows"), 3, true)(_.hasLabel(Ontology("Officer"))).withGraph(graph).toList //repeats three times at most if there are outgoing "knows" edges and the result is not of type "Officer" and returns every result in between
// res34: List[Any] = List() //repeats three times at most if there are outgoing "knows" edges and the result is not of type "Officer" and returns every result in between
g.N.repeat(_.out("knows"), collect = true)(_.hasLabel(Ontology("Officer"))).withGraph(graph).toList //repeats as long as there are outgoing "knows" edges and the result is not of type "Officer" and returns every result in between
// res35: List[Any] = List() //repeats as long as there are outgoing "knows" edges and the result is not of type "Officer" and returns every result in between
g.N.repeat(_.out("knows"), max = 3).withGraph(graph).toList //repeats three times at most if there are outgoing "knows" edges
// res36: List[Any] = List() //repeats three times at most if there are outgoing "knows" edges
g.N.repeat(_.out("knows"), max = 3, collect = true).withGraph(graph).toList //repeats three times at most if there are outgoing "knows" edges and returns every result in between
// res37: List[Any] = List()
Coalesce
Coalesce-step takes one or more traversals and returns the result of the first non-empty traversal
g.N.coalesce(_.has(keys.rate, P.gte(4)).iri, _.has(keys.balance, P.lt(-200)).iri).withGraph(graph).head
// res38: String = "librarian-doc/person/567"
Choose
Choose-step takes a right or left traversal, right if the by-traversal is non-empty, left if it is empty.
g.N.choose(_.has(keys.rate, P.gte(4)), _.constant(true), _.constant(false)).withGraph(graph).toList
// res39: List[Boolean] = List(
// true,
// false,
// false,
// false,
// false,
// false,
// false,
// false,
// false,
// true,
// false
// )
g.N.hasIri(graph.iri + "/place/123").choose(_.count.is(P.eqv(1)), _.constant(true), _.constant(false)).withGraph(graph).head
// res40: Boolean = true
Traverse steps
Id
Id-step returns the resource-id (long)
g.N.id.withGraph(graph).toList
// res41: List[Long] = List(
// 1286L,
// 1095L,
// 1304L,
// 1054L,
// 1247L,
// 1127L,
// 1001L,
// 1268L,
// 1206L,
// 1144L,
// 1017L
// )
Constant
Constant-step returns a traverser with the provided constant-value
g.N.constant(42).withGraph(graph).head
// res42: Int = 42
From
From-step …
g.E.from.withGraph(graph).toList
// res43: List[Any] = List(
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3fc,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$8@5db0e419,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3fc,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$8@5db0e433,
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e44a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e44a,
// ...
To
To-step …
g.E.to.withGraph(graph).toList
// res44: List[Any] = List(
// 500.5,
// "librarian-doc/person/123",
// 2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// "Yoshio",
// "librarian-doc/person/567",
// "Stan",
// 1996-08-18,
// 2002-06-13,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3fc,
// 300,
// 4,
// "San Jos\u00e9 de Maipo",
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// 5L,
// "librarian-doc/person/56789",
// "Garrison",
// 10.34,
// Point(x = 72.0403, y = 60.90879),
// 1994-06-18,
// lspace.provider.mem.MemGraph$$anon$7@5db0e46a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// "librarian-doc/place/12345",
// 4,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// "Crystal Springs",
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// "librarian-doc/person/12345",
// 4L,
// Point(x = -48.4046, y = 175.87173),
// "Levi",
// 2008-12-20,
// "librarian-doc/place/345",
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// -245.05,
// "Haridwar",
// ...
Projection steps
Project
Path
Select
Map steps
Map steps …
OutMap
OutMap-step groups the resultset into a Map[Property,List[Value]]
where OutMap is the edge label by which it is grouped and
List[Value]
is the list of values for a certain Property. If the traversal has any succeeding steps after the OutMap-step,
the traversal will continue to operate with a traverser for each Value.
```scala mdoc
g.N.outMap() //returns a property-map on all out-going connected resources
g.N.has(“name”, P.eqv(“Garrison”)).outMap().withGraph(graph).head
g.N.outMap(“name”, “knows”) //returns a property-map for edges with label “name” or “knows”
##### OutEMap
```scala
g.N.has("name", P.eqv("Garrison")).outEMap().withGraph(graph).head //should return all out-going edges grouped by key
// res45: Map[Property, List[Edge[Node, Any]]] = HashMap(
// property:name -> List(lspace.provider.mem.MemGraph$$anon$8@5db0e51f),
// property:https://example.org/birthPlace -> List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e522
// ),
// property:address -> List(lspace.provider.mem.MemGraph$$anon$8@5db0e523),
// property:@id -> List(lspace.provider.mem.MemGraph$$anon$8@5db0e51d),
// property:https://example.org/birthDate -> List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e521
// ),
// property:https://example.org/knows -> List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e524,
// lspace.provider.mem.MemGraph$$anon$8@5db0e527
// )
// )
InMap
g.N.has("name", P.eqv("Garrison")).inMap().withGraph(graph).head //returns a property-map on all incoming connected resources
// res46: Map[Property, List[Any]] = Map(
// property:https://example.org/knows -> List(
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e509
// )
// )
InEMap
g.N.has("name", P.eqv("Garrison")).inEMap().withGraph(graph).head //should return all in-coming edges grouped by key
// res47: Map[Property, List[Edge[Any, Node]]] = Map(
// property:https://example.org/knows -> List(
// lspace.provider.mem.MemGraph$$anon$8@5db0e529,
// lspace.provider.mem.MemGraph$$anon$8@5db0e525
// )
// )
Barrier steps
Barrier steps can operate on the entire resultset of a traversal
Collecting barrier steps
Collecting steps …
Group
Group-step groups the resultset into a Map[Key,List[Value]]
where Key is the value by which it is grouped and
List[Value]
is the list of values which have the same group-key. If the traversal has any succeeding steps after the Group-step,
the traversal will continue to operate with a traverser for each Value.
```scala mdoc
g.N.group(.out(“name”)).mapValues(.iri).withGraph(graph).head //groups only on nodes with a “name” and only takes the first result (head)
g.N.group(.out(“name”)).mapValues(.group(.out(“age”)).mapValues(.iri)).withGraph(graph).head //can e.g. be a Map[String, List[Map[Int,List[Node]]]]
#### Reducing barrier steps
Reducing barrier steps perform a fold task on all traverers in the stream resulting in a single traverser
with the resulting value of the fold task.
##### Mean
Mean-step passes a traverser where the value is the mean of the values of incoming traversers
```scala
g.N.out("balance").hasLabel(`@double`).mean.withGraph(graph).head //should be 624.0225
// res48: Double = 624.0225
Sum
Sum-step passes a traverser where the value is the sum of the values of incoming traversers
g.N.out("balance").hasLabel(`@double`).sum.withGraph(graph).head //should be 2496.09
// res49: Double = 2496.09
Filter barrier steps
Filter barrier steps filters traversers based on some comparison against the complete stream of traversers.
Min
Min-step passes only the traverser with the smallest value
g.N.out("balance").hasLabel(`@double`).min.withGraph(graph).head //should be -245.05
// res50: Double = -245.05 //should be -245.05
g.N.out("balance").hasLabel(`@double`).min.in("balance").out("name").withGraph(graph).head //should be "Levi"
// res51: Any = "Levi"
Max
Max-step passes only the traverser with the largest value
g.N.out("balance").hasLabel(`@double`).max.withGraph(graph).head //should be 2230.30
// res52: Double = 2230.3 //should be 2230.30
g.N.out("balance").hasLabel(`@double`).max.in("balance").out("name").withGraph(graph).head //should be "Gray"
// res53: Any = "Gray"
Rearrange barrier steps
Rearrange barrier steps manipulates the position of all the traversers in the stream.
Order
Order-step sorts the resultset
Head
Head-step takes the first traverser
g.N.head.iri.withGraph(graph).head //takes only the first node
// res54: String = "librarian-doc/person/567" //takes only the first node
g.N.group(_.out("name").head).mapValues(_.iri).withGraph(graph).toList //
// res55: List[(Option[Any], List[String])] = List(
// (Some(value = "Haridwar"), List("librarian-doc/place/345")),
// (Some(value = "Garrison"), List("librarian-doc/person/56789")),
// (Some(value = "Gray"), List("librarian-doc/person/345")),
// (Some(value = "Crystal Springs"), List("librarian-doc/place/12345")),
// (None, List()),
// (Some(value = "Levi"), List("librarian-doc/person/12345")),
// (Some(value = "Yoshio"), List("librarian-doc/person/123")),
// (Some(value = "San Jos\u00e9 de Maipo"), List("librarian-doc/place/123")),
// (Some(value = "Kevin"), List("librarian-doc/person/34567")),
// (Some(value = "Talca"), List("librarian-doc/place/34567")),
// (Some(value = "Stan"), List("librarian-doc/person/567"))
// )
Last
Last-step takes the last traverser
g.N.last.iri.withGraph(graph).head //takes only the last 12 nodes
// res56: String = "librarian-doc/place/123" //takes only the last 12 nodes
g.N.group(_.out("name").last).mapValues(_.iri).withGraph(graph).toList //
// res57: List[(Option[Any], List[String])] = List(
// (Some(value = "Haridwar"), List("librarian-doc/place/345")),
// (Some(value = "Garrison"), List("librarian-doc/person/56789")),
// (Some(value = "Gray"), List("librarian-doc/person/345")),
// (Some(value = "Crystal Springs"), List("librarian-doc/place/12345")),
// (None, List()),
// (Some(value = "Levi"), List("librarian-doc/person/12345")),
// (Some(value = "Yoshio"), List("librarian-doc/person/123")),
// (Some(value = "San Jos\u00e9 de Maipo"), List("librarian-doc/place/123")),
// (Some(value = "Kevin"), List("librarian-doc/person/34567")),
// (Some(value = "Talca"), List("librarian-doc/place/34567")),
// (Some(value = "Stan"), List("librarian-doc/person/567"))
// )
Count
Count-step returns the number of incoming traversers
g.N.hasLabel(Ontology("https://example.org/Person")).count.withGraph(graph).head //should be 6
// res58: Long = 6L //should be 6
g.N.hasLabel(Ontology("https://example.org/Person")).where(_.out(Property("https://example.org/knows")).count.is(P.gt(1))).count.withGraph(graph).head //should be 5
// res59: Long = 5L //should be 5
g.N.hasLabel(Ontology("https://example.org/Person")).where(_.out(Property("https://example.org/knows")).count.is(P.lt(2))).count.withGraph(graph).head //should be 1
// res60: Long = 1L
Side-Effect steps
Side-Effect steps …
Drop
Drop-step removes selected resources from the graph (Only for editable graphs)
Environment steps
Environment steps adjust the context of the traversal
TimeLimit
TimeLimit-step limits the amount of time the rest of the traversal may take
g.N.timeLimit(20).withGraph(graph).toList
// res61: List[Node] = List(
// lspace.provider.mem.MemGraph$$anon$7@5db0e509,
// lspace.provider.mem.MemGraph$$anon$7@5db0e44a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e51b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e421,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4e2,
// lspace.provider.mem.MemGraph$$anon$7@5db0e46a,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3ec,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4f7,
// lspace.provider.mem.MemGraph$$anon$7@5db0e4b9,
// lspace.provider.mem.MemGraph$$anon$7@5db0e47b,
// lspace.provider.mem.MemGraph$$anon$7@5db0e3fc
// )