A slim wrapper to make Gremlin - a JVM graph traversal library - usable from Scala. This is the current development branch for Apache Tinkerpop3. The old version for Tinkerpop 2 is still in the 2.x branch.
- Scala friendly function signatures, aiming to be close to the standard collection library
- Nicer DSL e.g. to create vertices and edges
- You can use standard Scala functions instead of having to worry about how to implement things like
java.util.function.BiPredicate
- Nothing is hidden away, you can always easily access the Gremlin-Java objects if needed. Examples include accessing graph db specifics things like indexes, or using a step that hasn't been implemented in Gremlin-Scala yet
- Minimal overhead - only allocates additional instances if absolutely necessary
The examples project comes with working examples for different graph databases.
- tl;dr:
sbt gremlin-scala/console
- start
sbt
in the root project
> projects
[info] gremlin-scala
[info] macros
[info] * root
>
- Next, change to the gremlin-scala project using
project gremlin-scala
- Finally, to test out the API in a REPL type
console
import gremlin.scala._
import gremlin.scala.schema.Key
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph
val graph = TinkerGraph.open.asScala
// create labelled vertex
val paris = graph + "Paris"
// create vertex with typed properties
object Founded extends Key[String]("founded")
val london = graph + ("London", Founded("43 AD"))
// create labelled edges
paris --- "OneWayRoad" --> london
paris <-- "OtherWayAround" --- london
// create labelled bidirectional edge
paris <-- "Eurostar" --> london
// create edge with typed properties
object Name extends Key[String]("name")
paris <-- ("EuroStar", Name("TrainName")) --- london
Many thanks to @dkrieg for contributing this. For more details check out the SchemaSpec.
Gremlin-Scala aims to helps you at compile time as much as possible. Take this simple example:
import gremlin.scala._
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph
val graph = TinkerGraph.open.asScala
graph.V.outE.inV //compiles
graph.V.outE.outE //does _not_ compile
In standard Gremlin there's nothing stopping you to create the first traversal - it will explode at runtime, as outgoing edges do not have outgoing edges. This is simply an invalid step and we can use the compiler to help us.
Gremlin-Scala has support for full type safety in a traversal. You can label any step you want and in the end call labelledPath
- you will the values in each labelled step as an HList. That's a type safe list, i.e. the compiler guarantees the types, which also helps you auto-complete in your IDE. In contrast: in Java and Groovy you would have to cast to the type you think it will be, which is ugly and error prone.
For example:
import gremlin.scala._
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory
val graph = TinkerFactory.createModern.asScala
val traversal = graph.V.as("a").out.value[String]("name").as("b").labelledPath
traversal.toList
// returns `Vertex :: String :: HNil` for each path
You can label as many steps as you like and Gremlin-Scala will preserve the types for you. For more examples see LabelledPathSpec.
In comparison: Gremlin-Java and Gremlin-Groovy just return a List[Any]
and you then have to cast the elements - the types got lost on the way. Kudos to shapeless and Scala's sophisticated type system that made this possible.
You can save and load case classes as a vertex - this is still experimental but pretty cool. Note: this does not work in a REPL, you have to put it into a test. For examples check out the MarshallerSpec.
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph
val graph = TinkerGraph.open.asScala
case class Example(i: Int, s:Option[String])
it("load a vertex into a case class") {
val graph = TinkerGraph.open.asScala
val example = Example(Int.MaxValue, Some("optional value"))
val v = graph.addVertex(example)
v.toCC[Example] shouldBe example
}
Note that you can also use Options as the example shows. Thanks to joan38 for contributing this feature!
If you would like to help, here's a list of things that needs to be addressed:
- add more graph databases and examples into the examples project
- port over more TP3 steps - see TP3 testsuite and Gremlin-Scala StandardTests
- fill this readme and provide other documentation, or how-tos, e.g. a blog post or tutorial
For more information about Gremlin see the Gremlin docs and the Gremlin users mailinglist. Please note that while Gremlin-Scala is very close to the original Gremlin, there a slight differences to Gremlin-Groovy - don't be afraid, they hopefully all make sense to a Scala developer ;)
Random links: