https://github.com/outworkers/reactiveneo
[DISCONTINUED] Reactive type-safe Scala driver for Neo4J
https://github.com/outworkers/reactiveneo
Last synced: 12 months ago
JSON representation
[DISCONTINUED] Reactive type-safe Scala driver for Neo4J
- Host: GitHub
- URL: https://github.com/outworkers/reactiveneo
- Owner: outworkers
- License: gpl-2.0
- Created: 2014-08-15T19:17:52.000Z (over 11 years ago)
- Default Branch: develop
- Last Pushed: 2015-09-20T21:02:14.000Z (over 10 years ago)
- Last Synced: 2025-03-30T09:41:25.116Z (about 1 year ago)
- Language: Scala
- Homepage: http://outworkers.github.io/reactiveneo
- Size: 541 KB
- Stars: 69
- Watchers: 7
- Forks: 7
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# reactiveneo [](https://travis-ci.org/websudos/reactiveneo) [](https://maven-badges.herokuapp.com/maven-central/com.websudos/reactiveneo_2.10)
Reactive type-safe Scala DSL for Neo4j
# Table of contents
The library enforces strong type checks that imposes some restrictions on query format. Every node and relationship
used in the query needs to be defined and named.
E.g. this kind of query is not supported:
```
MATCH (wallstreet { title:'Wall Street' })<-[r:ACTED_IN]-(actor)
RETURN r
```
Instead you will need to use proper labels for nodes to produce the following query:
```
MATCH (wallstreet:Movie { title:'Wall Street' })<-[r:ACTED_IN]-(actor:Actor)
RETURN r
```
# Getting it
```scala
libraryDependencies ++= Seq(
"com.websudos" %% "reactiveneo-dsl" % "0.3.0",
"com.websudos" %% "reactiveneo-testing" % "0.3.0"
)
```
# Graph modelling
Back to top
## Nodes
Back to top
Domain model class
```
case class Person(name: String, age: Int)
```
Reactiveneo node definition
```
import com.websudos.reactiveneo.dsl._
class PersonNode extends Node[PersonNode, Person] {
object name extends StringAttribute with Index
object age extends IntegerAttribute
def fromNode(data: QueryRecord): Person = {
Person(name[String](data), age[Int](data))
}
}
```
## Relationships
Back to top
Reactiveneo relationship definition
```
import com.websudos.reactiveneo.dsl._
class PersonRelation extends Relationship[PersonRelation, Person] {
object name extends StringAttribute with Index
object age extends IntegerAttribute
def fromNode(data: QueryRecord): Person = {
Person(name[String](data), age[Int](data))
}
}
```
## Indexes
Back to top
# Querying
Back to top
## Connection
Prerequisite to making Neo4j requests is REST endpoint definition. This is achived using RestConnection class.
```
scala> implicit val service = RestConnection("localhost", 7474)
service: RestConnection
```
## Making requests
In this example all nodes of Person type are returned.
```
scala> val personNodes = Person().returns(case p ~~ _ => p).execute
personNodes: Future[Seq[Person]]
```
The strange construct in the returns function is execution of extractor in the pattern. Pattern defines set of objects
that participate in the query. The objects are nodes and relationships.
You can also query for specific attributes of a node.
```
scala> val personNames = Person().returns(case p ~~ _ => p.name).execute
personNames: Future[Seq[String]]
```
A query that involves attributes matching.
```
scala> val personNodes = Person(_.name := "Tom").returns(case p ~~ _ => p).execute
personNodes: Future[Seq[Person]]
```
Query for a person that has a relationship to another person
```
scala> val personNodes = (Person() :->: Person())
.returns(case p1 ~~ _ => p).execute
personNodes: Future[Seq[Person]]
```
Query for a person that has a relationship to another person with given name
```
scala> val personNodes = (Person() :->: Person(_.name := "James"))
.returns(case p ~~ _ => p).execute
personNodes: Future[Seq[Person]]
```
Query for a person that has a relationship to another person
```
scala> val personNodes = (Person() :<-: WorkRelationship() :->: Person())
.returns(case p1 ~~ r ~~ p2 ~~ _ => p1).execute
personNodes: Future[Seq[Person]]
```
Query for a person that has a relationship to another person with given name
```
scala> val personNodes = (Person() :-: WorkRelationship(_.company := "ABC") :->: Person(_.name := "John"))
.returns(case p1 ~~ _ => p1).execute
personNodes: Future[Seq[Person]]
```
## An arbitrary Cypher query
Cypher is a rich language and whenever you need to use it directly escaping the abstraction layer it's still possible
with ReactiveNeo. Use the same REST connection object with an arbitrary Cypher query.
```
scala> val query = "MATCH (n:Person) RETURN n"
query: String
implicit val parser: Reads[Person] = ((__ \ "name").read[String] and (__ \ "age").read[Int])(Person)
parser: Reads[Person]
val result = service.makeRequest[Person](query).execute
result: Future[Seq[Person]]
```