-
Notifications
You must be signed in to change notification settings - Fork 6
Examples
Patterns
Clauses
⎿ MATCH
⎿ OPTIONAL MATCH
⎿ RETURN
⎿ WITH
⎿ ORDER BY
⎿ SKIP
⎿ LIMIT
⎿ CREATE
⎿ MERGE
⎿ DELETE
⎿ SET
Operators
no special pattern is required, it is the instance of case class itself.
val johnDoe = Person(id=1000, name="John Doe",age=20)
cypher.MATCH(johnDoe)
such case classes are enriched implicitly and provide apply method which takes 1 or more symbols.
//MATCH John Doe for name
cypher.MATCH(johnDoe('name))
//MATCH John Doe for name and age
cypher.MATCH(johnDoe('name, 'age))
val anyPerson = any[Person]
cypher.MATCH(anyPerson)
val anything = anyNode
cypher.MATCH(anything)
val anyWorksInRelation = anyRel[WorksIn]
cypher.MATCH(anyWorksInRelation)
val anything = anyRelation
cypher.MATCH(anything)
You can use above defined patterns to make relationship paths. consider below as an example of path
//any person who works in same dept as JohnDoe
val colleague = johnDoe --> any[Department] <-| worksIn |- any[Person]
an important point to note is since we are going to work in type safe way and only with instances, we should avoid inline instance creation. The above example is better rewritten as
val anyDepartment = any[Department]
val anyPerson = any[Person]
val colleague = johnDoe --> anyDepartment <-| worksIn |- anyPerson
//with this we ensure that we are returning right identifier whenever we return like below
val result = cypher.MATCH(colleague).RETURN(anyPerson)
Below are tested paths where A
, B
and C
are either of case class
,any[T]
,anyRel[T]
,anyNode
or anyRelation
and {} indicates at-least one property is selected (when A
,B
or C
is case class
).
A -- B
A -- B{}
A{} -- B
A{} -- B{}
A --> B
A --> B{}
A{} --> B
A{} --> B{}
A <-- B
A <-- B{}
A{} <-- B
A{} <-- B{}
A -[C]- B
A -[C|D]- B
A{} -[C]- B{}
A -[C {}]- B
A{} -[C {}]- B{}
A -[C]-> B
A{} -[C]-> B{}
A -[C {}]-> B
A{} -[C {}]-> B{}
A <-[C]- B
A{} <-[C]- B{}
A <-[C {}]- B
A{} <-[C {}]- B{}
(A)-[R]-(B)-[R2]-(A2)
(A)-[R]->(B)-[R2]->(A2)
(A)<-[R]-(B)<-[R2]-(A2)
(A)<-[R]-(B)-[R2]->(A2)
(A)-[R]->(B)<-[R2]-(A2)
(A)<-[R]-(B)<-[R2]-(A2)-->(C)
A -[*1..3]- B
A -[*1]- B
A -[*]- B
A -[C*]- B
A -[C*1]- B
A -[C*1..3]- B
A -[C{}*]- B
A -[C{}*1]- B
A -[C{}*1..3]- B
A{} -[*1..3]- B{}
A{} -[*1]- B{}
A{} -[*]- B{}
A{} -[C*1..3]- B{}
A{} -[C*1]- B{}
A{} -[C*]- B{}
A{} -[C{}*1..3]- B{}
A{} -[C{}*1]- B{}
A{} -[C{}*]- B{}
match a particular path or a node.
cypher
.MATCH(johnDoe)
.MATCH(johnDoe -| worksIn |-> anyDept)
.RETURN(anyDept)
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
RETURN a2
*/
match optionally a particular path or a node.
cypher
.MATCH(johnDoe)
.OPTIONAL_MATCH(johnDoe -| worksIn |-> anyDept)
.RETURN(anyDept)
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
OPTIONAL MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
RETURN a2
*/
returns multiple node/relations or any attributes of the same. Also allows aliasing the identifier.
cypher
.MATCH(johnDoe)
.MATCH(johnDoe -| worksIn |-> anyDept)
.RETURN(johnDoe('name), anyDept -> "department")
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
RETURN a0.name,a2 as department
*/
allows query scoping. Allows aliasing of identifiers and updates the context to use the same going forward.
cypher
.MATCH(johnDoe)
.MATCH(johnDoe -| worksIn |-> anyDept)
.WITH(johnDoe, Distinct(anyDept -> "department"))
.RETURN(johnDoe('name) -> "name", anyDept)
.toQuery(new Context())
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
WITH a0,DISTINCT a2 as department
RETURN a3.name as name,department
*/
allows ordering of result (ascending or descending).
cypher
.MATCH(johnDoe)
.MATCH(johnDoe -| worksIn |-> anyDept)
.WITH(johnDoe, Distinct(anyDept -> "department"))
.RETURN(johnDoe('name) -> "name", anyDept)
.ORDER_BY(anyDept)
.toQuery(new Context())
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
WITH a0,DISTINCT a2 as department
RETURN a3.name as name,department
ORDER BY department
*/
allows scoping for results.
cypher
.MATCH(johnDoe)
.MATCH(johnDoe -| worksIn |-> anyDept)
.SKIP(5)
.LIMIT(10)
.ORDER_BY(anyDept)
.toQuery(new Context())
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a0)-[a1:WORKS_IN]->(a2:Department)
SKIP 5
LIMIT 10
ORDER BY a2
*/
create a node/relationship.
cypher
.CREATE(johnDoe)
.RETURN(johnDoe)
.toQuery()
/*
CREATE (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
RETURN a0
*/
merges a node/relationship.
cypher
.MATCH(johnDoe)
.MATCH(scienceDept)
.MERGE(johnDoe -| worksIn |-> scienceDept)
.RETURN(worksIn)
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
MATCH (a1:Department {id: {a1_id},name: {a1_name}})
MERGE (a0)-[a2:WORKS_IN]->(a1)
RETURN a2
*/
deletes a node/relationship.DETACH DELETE
detaches all relationships before deletion.
cypher
.MATCH(johnDoe -| anyWorksIn |-> scienceDept)
.DELETE(anyWorksIn)
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})-[a1:WORKS_IN]->(a2:Department {id: {a2_id},name: {a2_name}})
DELETE a1
*/
cypher
.MATCH(johnDoe)
.DETACH_DELETE(johnDoe)
.toQuery()
/*
MATCH (a0:Person {id: {a0_id},name: {a0_name},age: {a0_age}})
DETACH DELETE a0
*/
sets property of a node/relation or node/relation itself.
//set age of John Doe to 35, and nationality as Latvian.
cypher
.MATCH(johnDoe('name))
.SET(johnDoe('age) -> 35, johnDoe('nationality) -> "Latvia")
.toQuery()
/*
MATCH (a0:Person {name: {a0_name}})
SET a0.age = {a0_age},a0.nationality = {a0_nationality}
*/
//set John Doe node as a whole
cypher
.MATCH(johnDoe('name))
.SET(johnDoe, List(johnDoe('age) -> 35, johnDoe('nationality) -> "Latvia"))
.toQuery()
/*
MATCH (a0:Person {name: {a0_name}})
SET a0 = {age = {a0_age},nationality = {a0_nationality}}
*/
Currently, supported by WITH
and RETURN
clauses only. modifies the context to use the alias as the new identifier.
cypher
.MATCH(johnDoe -| worksIn |-> anyDept)
.WITH(Distinct(anyDept -> "depts"))
.RETURN(anyDept)