Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active April 2, 2023 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/858079060940ccc4bd72660f5b60e023 to your computer and use it in GitHub Desktop.
Save dacr/858079060940ccc4bd72660f5b60e023 to your computer and use it in GitHub Desktop.
playing with arangodb graph using java driver and json4s serdes / published by https://github.com/dacr/code-examples-manager #c952cf03-09c4-4f84-8ce9-c8ccb0165ddf/2db1e810f9800d7eafedfc523385fbcd800fc798
// summary : playing with arangodb graph using java driver and json4s serdes
// keywords : arangodb, graphdb, graph, javadriver, velocity, graph
// publish : gist, corporate
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : c952cf03-09c4-4f84-8ce9-c8ccb0165ddf
// created-on : 2021-03-05T09:25:00Z
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// ---------------------
//> using scala "3.1.1"
//> using dep "org.scalatest::scalatest:3.2.10"
//> using dep "com.arangodb:arangodb-java-driver:6.14.0"
//> using dep "org.json4s::json4s-native:4.0.3"
//> using dep "org.json4s::json4s-ext:4.0.3"
//> using dep "org.slf4j:slf4j-simple:1.7.30"
// ---------------------
import org.json4s.*
import org.json4s.DefaultFormats
import org.json4s.native.Serialization.{read, write}
import scala.jdk.CollectionConverters.*
implicit val formats: Formats = DefaultFormats.lossless // for milliseconds in iso8601 dates...
import com.arangodb._
import com.arangodb.entity._
import com.arangodb.model.AqlQueryOptions
import com.arangodb.util.MapBuilder
val arango = {
new ArangoDB.Builder()
.host("127.0.0.1", 8529)
.user("root")
.password("root")
.build()
}
val databaseName = "graph-sand-box"
val graphName = "graph-example"
val edgesCollectionName = "links"
val verticesCollectionName = "nodes"
val db = arango.db(databaseName)
if (db.exists()) db.drop()
arango.createDatabase(databaseName)
val edgeDefinition = new EdgeDefinition().collection(edgesCollectionName).from(verticesCollectionName).to(verticesCollectionName)
val graph = db.graph(graphName)
if (!graph.exists()) db.createGraph(graph.name, java.util.List.of(edgeDefinition), null)
def addVertex[T](vertex: T): VertexEntity = {
graph.vertexCollection(verticesCollectionName).insertVertex(write(vertex))
}
def removeVertex(key: String): Unit = {
graph.vertexCollection(verticesCollectionName).deleteVertex(key)
}
def addEdge[T](edge: T): EdgeEntity = {
graph.edgeCollection(edgesCollectionName).insertEdge(write(edge))
}
case class Node(name: String, _key:String)
case class Link(name: String, _from: String, _to: String)
val a = addVertex(Node("A", "a"))
val b = addVertex(Node("B", "b"))
val c = addVertex(Node("C", "c"))
val d = addVertex(Node("D", "d"))
val e = addVertex(Node("E", "e"))
val f = addVertex(Node("F", "f"))
addEdge(Link("like", a.getId, b.getId))
addEdge(Link("like", b.getId, c.getId))
addEdge(Link("like", c.getId, d.getId))
addEdge(Link("like", d.getId, a.getId))
addEdge(Link("dislike", a.getId, e.getId))
addEdge(Link("like", e.getId, b.getId))
addEdge(Link("like", e.getId, f.getId))
addEdge(Link("dislike", f.getId, e.getId))
// ALSO AUTOMATICALLY REMOVE EDGES INVOLVED WITH F BECAUSE graph.vertexCollection(...).deleteVertex is USED !!!
removeVertex(f.getKey) // BUT IF YOU USE AQL OR STANDARD COLLECTIONS THIS IS NOT THE CASE, YOU'LL HAVE TO REMOVE EDGES BY HAND !!!
/*
/<------------------\
a--------->b--->c--->d
\--->e--->/
*/
def vars(tuples: (String, Object)*): java.util.Map[String, Object] = {
tuples.toMap.asJava
}
def query(query: String, vars: (String, Object)*) = {
db.query(query, vars.toMap.asJava, null, classOf[String])
}
def queryDoc(query: String, vars: (String, Object)*) = {
db.query(query, vars.toMap.asJava, null, classOf[BaseDocument])
}
println("------------------------------------------------------------")
val nodes = queryDoc(
"""FOR n IN @@nodes RETURN n""",
"@nodes"->verticesCollectionName
)
println("nodes : \n"+nodes.asListRemaining().asScala.mkString("\n"))
println("------------------------------------------------------------")
val edges = queryDoc(
"""FOR l IN @@edges RETURN l""",
"@edges"->edgesCollectionName
)
println("edges : \n"+edges.asListRemaining().asScala.mkString("\n"))
println("------------------------------------------------------------")
val q0 = query(
"""FOR v IN 1..1 OUTBOUND @node GRAPH @graph RETURN {"name":v.name, "key":v._key}""",
"graph" -> graphName, "node" -> a.getId)
println("A children : " + q0.asListRemaining().asScala.mkString(","))
println("------------------------------------------------------------")
val q1 = query(
"""FOR v IN 1..1 INBOUND @node GRAPH @graph RETURN {"name":v.name, "key":v._key}""",
"graph" -> graphName, "node" -> a.getId)
println("A parents : " + q1.asListRemaining().asScala.mkString(","))
println("------------------------------------------------------------")
val q2 = query(
"FOR v IN 3..3 OUTBOUND @node GRAPH @graph RETURN v.name",
"graph" -> graphName, "node" -> a.getId)
println("sub-children at depth 3 :"+q2.asListRemaining().asScala.mkString(", "))
println("------------------------------------------------------------")
// ANY means INBOUND or OUTBOUND
val q3 = query(
"""FOR vertex,edge,path IN 1..3 ANY @node GRAPH @graph RETURN CONCAT_SEPARATOR("/",vertex.name, edge.name, path.edges)""",
"graph" -> graphName, "node" -> a.getId)
println("from A :\n"+q3.asListRemaining().asScala.mkString("\n"))
arango.shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment