ArangoDB in Akka

Implementation of ArangoDB with Akka

Arango client database is written with akka I/O TCP and query streaming with akka streams

Installation

// add dependency to the arangodb client
libraryDependencies += "com.bicou" %% "avokka-arangodb-akka" % "0.0.7"

Usage

An implicit akka actor system

import akka.actor.ActorSystem
implicit def actorSystem: ActorSystem = ???

and an arango configuration

import avokka.arangodb.ArangoConfiguration
val configuration = ArangoConfiguration.load()

build an arangodb client

import avokka.arangodb.akka._
val arango = Arango(configuration)

arango is an instance of ArangoClient[Future]

Query result streaming with akka streams

Model of arangodb document with a generated velocypack decoder :

import avokka.arangodb.types._
import avokka.velocypack._

case class Country(_key: DocumentKey, name: String)
object Country {
  implicit val decoder: VPackDecoder[Country] = VPackDecoder.derived
}

simple query

val countries: Source[Country, NotUsed] = arango.db.query(
  "FOR c IN countries RETURN c"
).stream[Country]
// countries: Source[Country, NotUsed] = Source(SourceShape(CursorSource.out(1820690120)))

Await.result(countries.runWith(Sink.seq), 10.seconds)
// res0: Seq[Country] = Vector(
//   Country(_key = DocumentKey(repr = "AI"), name = "Anguilla"),
//   Country(_key = DocumentKey(repr = "AF"), name = "Afghanistan"),
//   Country(_key = DocumentKey(repr = "AR"), name = "Argentina"),
//   Country(_key = DocumentKey(repr = "AO"), name = "Angola"),
//   Country(_key = DocumentKey(repr = "AM"), name = "Armenia"),
//   Country(_key = DocumentKey(repr = "AW"), name = "Aruba"),
//   Country(_key = DocumentKey(repr = "AS"), name = "American Samoa"),
//   Country(_key = DocumentKey(repr = "AD"), name = "Andorra"),
// ...

bind vars as argument

val countriesArg: Source[Country, NotUsed] = arango.db.query(
  "FOR c IN countries FILTER CONTAINS(c.name, @name) RETURN c", VObject("name" -> "Fra".toVPack)
).stream[Country]
// countriesArg: Source[Country, NotUsed] = Source(SourceShape(CursorSource.out(1800935165)))

Await.result(countriesArg.runWith(Sink.head), 10.seconds)
// res1: Country = Country(_key = DocumentKey(repr = "FR"), name = "France")

with aql interpolator

import avokka.arangodb.aql._
val name = "Fra"
// name: String = "Fra"
val countriesAql: Source[Country, NotUsed] = arango.db.query(
  aql"FOR c IN countries FILTER CONTAINS(c.name, $name) RETURN c"
).stream[Country]
// countriesAql: Source[Country, NotUsed] = Source(SourceShape(CursorSource.out(1766538122)))

Await.result(countriesAql.runWith(Sink.head), 10.seconds)
// res2: Country = Country(_key = DocumentKey(repr = "FR"), name = "France")

or bind

val countriesBind: Source[Country, NotUsed] = arango.db.query(
  aql"FOR c IN countries FILTER CONTAINS(c.name, @name) RETURN c".bind("name", name)
).stream[Country]
// countriesBind: Source[Country, NotUsed] = Source(SourceShape(CursorSource.out(949947139)))

Await.result(countriesBind.runWith(Sink.head), 10.seconds)
// res3: Country = Country(_key = DocumentKey(repr = "FR"), name = "France")