QueryClauseMethods

The Neo4j::Core::Query class from the neo4j-core gem defines a DSL which allows for easy creation of Neo4j Cypher queries. They can be started from a session like so:

# The current session can be retrieved with `Neo4j::Session.current`
a_session.query

Advantages of using the Query class include:

  • Method chaining allows you to build a part of a query and then pass it somewhere else to be built further
  • Automatic use of parameters when possible
  • Ability to pass in data directly from other sources (like Hash to match keys/values)
  • Ability to use native Ruby objects (such as translating nil values to IS NULL, regular expressions to Cypher-style regular expression matches, etc...)

Below is a series of Ruby code samples and the resulting Cypher that would be generated. These examples are all generated directly from the spec file and are thus all tested to work.

Neo4j::Core::Query

#match

Ruby:
.match('n')
Cypher:
MATCH n

Ruby:
.match(:n)
Cypher:
MATCH n

Ruby:
.match(n: Person)
Cypher:
MATCH (n:`Person`)

Ruby:
.match(n: 'Person')
Cypher:
MATCH (n:`Person`)

Ruby:
.match(n: ':Person')
Cypher:
MATCH (n:Person)

Ruby:
.match(n: :Person)
Cypher:
MATCH (n:`Person`)

Ruby:
.match(n: [:Person, "Animal"])
Cypher:
MATCH (n:`Person`:`Animal`)

Ruby:
.match(n: ' :Person')
Cypher:
MATCH (n:Person)

Ruby:
.match(n: nil)
Cypher:
MATCH (n)

Ruby:
.match(n: 'Person {name: "Brian"}')
Cypher:
MATCH (n:Person {name: "Brian"})

Ruby:
.match(n: {name: 'Brian', age: 33})
Cypher:
MATCH (n {name: {n_name}, age: {n_age}})

Parameters: {:n_name=>"Brian", :n_age=>33}


Ruby:
.match(n: {Person: {name: 'Brian', age: 33}})
Cypher:
MATCH (n:`Person` {name: {n_Person_name}, age: {n_Person_age}})

Parameters: {:n_Person_name=>"Brian", :n_Person_age=>33}


Ruby:
.match('n--o')
Cypher:
MATCH n--o

Ruby:
.match('n--o').match('o--p')
Cypher:
MATCH n--o, o--p

#optional_match

Ruby:
.optional_match(n: Person)
Cypher:
OPTIONAL MATCH (n:`Person`)

Ruby:
.match('m--n').optional_match('n--o').match('o--p')
Cypher:
MATCH m--n, o--p OPTIONAL MATCH n--o

#using

Ruby:
.using('INDEX m:German(surname)')
Cypher:
USING INDEX m:German(surname)

Ruby:
.using('SCAN m:German')
Cypher:
USING SCAN m:German

Ruby:
.using('INDEX m:German(surname)').using('SCAN m:German')
Cypher:
USING INDEX m:German(surname) USING SCAN m:German

#where

Ruby:
.where()
Cypher:

Ruby:
.where({})
Cypher:

Ruby:
.where('q.age > 30')
Cypher:
WHERE (q.age > 30)

Ruby:
.where('q.age' => 30)
Cypher:
WHERE (q.age = {q_age})

Parameters: {:q_age=>30}


Ruby:
.where('q.age' => [30, 32, 34])
Cypher:
WHERE (q.age IN {q_age})

Parameters: {:q_age=>[30, 32, 34]}


Ruby:
.where('q.age IN {age}', age: [30, 32, 34])
Cypher:
WHERE (q.age IN {age})

Parameters: {:age=>[30, 32, 34]}


Ruby:
.where('q.name =~ ?', '.*test.*')
Cypher:
WHERE (q.name =~ {question_mark_param1})

Parameters: {:question_mark_param1=>".*test.*"}


Ruby:
.where('q.age IN ?', [30, 32, 34])
Cypher:
WHERE (q.age IN {question_mark_param1})

Parameters: {:question_mark_param1=>[30, 32, 34]}


Ruby:
.where('q.age IN ?', [30, 32, 34]).where('q.age != ?', 60)
Cypher:
WHERE (q.age IN {question_mark_param1}) AND (q.age != {question_mark_param2})

Parameters: {:question_mark_param1=>[30, 32, 34], :question_mark_param2=>60}


Ruby:
.where(q: {age: [30, 32, 34]})
Cypher:
WHERE (q.age IN {q_age})

Parameters: {:q_age=>[30, 32, 34]}


Ruby:
.where('q.age' => nil)
Cypher:
WHERE (q.age IS NULL)

Ruby:
.where(q: {age: nil})
Cypher:
WHERE (q.age IS NULL)

Ruby:
.where(q: {neo_id: 22})
Cypher:
WHERE (ID(q) = {ID_q})

Parameters: {:ID_q=>22}


Ruby:
.where(q: {age: 30, name: 'Brian'})
Cypher:
WHERE (q.age = {q_age} AND q.name = {q_name})

Parameters: {:q_age=>30, :q_name=>"Brian"}


Ruby:
.where(q: {age: 30, name: 'Brian'}).where('r.grade = 80')
Cypher:
WHERE (q.age = {q_age} AND q.name = {q_name}) AND (r.grade = 80)

Parameters: {:q_age=>30, :q_name=>"Brian"}


Ruby:
.where(q: {name: /Brian.*/i})
Cypher:
WHERE (q.name =~ {q_name})

Parameters: {:q_name=>"(?i)Brian.*"}


Ruby:
.where(name: /Brian.*/i)
Cypher:
WHERE (name =~ {name})

Parameters: {:name=>"(?i)Brian.*"}


Ruby:
.where(q: {age: (30..40)})
Cypher:
WHERE (q.age IN RANGE({q_age_range_min}, {q_age_range_max}))

Parameters: {:q_age_range_min=>30, :q_age_range_max=>40}


#where_not

Ruby:
.where_not()
Cypher:

Ruby:
.where_not({})
Cypher:

Ruby:
.where_not('q.age > 30')
Cypher:
WHERE NOT(q.age > 30)

Ruby:
.where_not('q.age' => 30)
Cypher:
WHERE NOT(q.age = {q_age})

Parameters: {:q_age=>30}


Ruby:
.where_not('q.age IN ?', [30, 32, 34])
Cypher:
WHERE NOT(q.age IN {question_mark_param1})

Parameters: {:question_mark_param1=>[30, 32, 34]}


Ruby:
.where_not(q: {age: 30, name: 'Brian'})
Cypher:
WHERE NOT(q.age = {q_age} AND q.name = {q_name})

Parameters: {:q_age=>30, :q_name=>"Brian"}


Ruby:
.where_not(q: {name: /Brian.*/i})
Cypher:
WHERE NOT(q.name =~ {q_name})

Parameters: {:q_name=>"(?i)Brian.*"}


Ruby:
.where('q.age > 10').where_not('q.age > 30')
Cypher:
WHERE (q.age > 10) AND NOT(q.age > 30)

Ruby:
.where_not('q.age > 30').where('q.age > 10')
Cypher:
WHERE NOT(q.age > 30) AND (q.age > 10)

#match_nodes

one node object

Ruby:
.match_nodes(var: node_object)
Cypher:
MATCH var WHERE (ID(var) = {ID_var})

Parameters: {:ID_var=>246}


integer

Ruby:
.match_nodes(var: 924)
Cypher:
MATCH var WHERE (ID(var) = {ID_var})

Parameters: {:ID_var=>924}


two node objects

Ruby:
.match_nodes(user: user, post: post)
Cypher:
MATCH user, post WHERE (ID(user) = {ID_user}) AND (ID(post) = {ID_post})

Parameters: {:ID_user=>246, :ID_post=>123}


node object and integer

Ruby:
.match_nodes(user: user, post: 652)
Cypher:
MATCH user, post WHERE (ID(user) = {ID_user}) AND (ID(post) = {ID_post})

Parameters: {:ID_user=>246, :ID_post=>652}


#unwind

Ruby:
.unwind('val AS x')
Cypher:
UNWIND val AS x

Ruby:
.unwind(x: :val)
Cypher:
UNWIND val AS x

Ruby:
.unwind(x: 'val')
Cypher:
UNWIND val AS x

Ruby:
.unwind(x: [1,3,5])
Cypher:
UNWIND [1, 3, 5] AS x

Ruby:
.unwind(x: [1,3,5]).unwind('val as y')
Cypher:
UNWIND [1, 3, 5] AS x UNWIND val as y

#return

Ruby:
.return('q')
Cypher:
RETURN q

Ruby:
.return(:q)
Cypher:
RETURN q

Ruby:
.return('q.name, q.age')
Cypher:
RETURN q.name, q.age

Ruby:
.return(q: [:name, :age], r: :grade)
Cypher:
RETURN q.name, q.age, r.grade

Ruby:
.return(q: :neo_id)
Cypher:
RETURN ID(q)

Ruby:
.return(q: [:neo_id, :prop])
Cypher:
RETURN ID(q), q.prop

#order

Ruby:
.order('q.name')
Cypher:
ORDER BY q.name

Ruby:
.order_by('q.name')
Cypher:
ORDER BY q.name

Ruby:
.order('q.age', 'q.name DESC')
Cypher:
ORDER BY q.age, q.name DESC

Ruby:
.order(q: :age)
Cypher:
ORDER BY q.age

Ruby:
.order(q: [:age, {name: :desc}])
Cypher:
ORDER BY q.age, q.name DESC

Ruby:
.order(q: [:age, {name: :desc, grade: :asc}])
Cypher:
ORDER BY q.age, q.name DESC, q.grade ASC

Ruby:
.order(q: {age: :asc, name: :desc})
Cypher:
ORDER BY q.age ASC, q.name DESC

Ruby:
.order(q: [:age, 'name desc'])
Cypher:
ORDER BY q.age, q.name desc

#limit

Ruby:
.limit(3)
Cypher:
LIMIT {limit_3}

Parameters: {:limit_3=>3}


Ruby:
.limit('3')
Cypher:
LIMIT {limit_3}

Parameters: {:limit_3=>3}


Ruby:
.limit(3).limit(5)
Cypher:
LIMIT {limit_5}

Parameters: {:limit_5=>5}


Ruby:
.limit(nil)
Cypher:


#with

Ruby:
.with('n.age AS age')
Cypher:
WITH n.age AS age

Ruby:
.with('n.age AS age', 'count(n) as c')
Cypher:
WITH n.age AS age, count(n) as c

Ruby:
.with(['n.age AS age', 'count(n) as c'])
Cypher:
WITH n.age AS age, count(n) as c

Ruby:
.with(age: 'n.age')
Cypher:
WITH n.age AS age

#create

Ruby:
.create('(:Person)')
Cypher:
CREATE (:Person)

Ruby:
.create(:Person)
Cypher:
CREATE (:Person)

Ruby:
.create(age: 41, height: 70)
Cypher:
CREATE ( {age: {age}, height: {height}})

Parameters: {:age=>41, :height=>70}


Ruby:
.create(Person: {age: 41, height: 70})
Cypher:
CREATE (:`Person` {age: {Person_age}, height: {Person_height}})

Parameters: {:Person_age=>41, :Person_height=>70}


Ruby:
.create(q: {Person: {age: 41, height: 70}})
Cypher:
CREATE (q:`Person` {age: {q_Person_age}, height: {q_Person_height}})

Parameters: {:q_Person_age=>41, :q_Person_height=>70}


Ruby:
.create(q: {Person: {age: nil, height: 70}})
Cypher:
CREATE (q:`Person` {age: {q_Person_age}, height: {q_Person_height}})

Parameters: {:q_Person_age=>nil, :q_Person_height=>70}


#create_unique

Ruby:
.create_unique('(:Person)')
Cypher:
CREATE UNIQUE (:Person)

Ruby:
.create_unique(:Person)
Cypher:
CREATE UNIQUE (:Person)

Ruby:
.create_unique(age: 41, height: 70)
Cypher:
CREATE UNIQUE ( {age: {age}, height: {height}})

Parameters: {:age=>41, :height=>70}


Ruby:
.create_unique(Person: {age: 41, height: 70})
Cypher:
CREATE UNIQUE (:`Person` {age: {Person_age}, height: {Person_height}})

Parameters: {:Person_age=>41, :Person_height=>70}


Ruby:
.create_unique(q: {Person: {age: 41, height: 70}})
Cypher:
CREATE UNIQUE (q:`Person` {age: {q_Person_age}, height: {q_Person_height}})

Parameters: {:q_Person_age=>41, :q_Person_height=>70}


#merge

Ruby:
.merge('(:Person)')
Cypher:
MERGE (:Person)

Ruby:
.merge(:Person)
Cypher:
MERGE (:Person)

Ruby:
.merge(age: 41, height: 70)
Cypher:
MERGE ( {age: {age}, height: {height}})

Parameters: {:age=>41, :height=>70}


Ruby:
.merge(Person: {age: 41, height: 70})
Cypher:
MERGE (:`Person` {age: {Person_age}, height: {Person_height}})

Parameters: {:Person_age=>41, :Person_height=>70}


Ruby:
.merge(q: {Person: {age: 41, height: 70}})
Cypher:
MERGE (q:`Person` {age: {q_Person_age}, height: {q_Person_height}})

Parameters: {:q_Person_age=>41, :q_Person_height=>70}


#delete

Ruby:
.delete('n')
Cypher:
DELETE n

Ruby:
.delete(:n)
Cypher:
DELETE n

Ruby:
.delete('n', :o)
Cypher:
DELETE n, o

Ruby:
.delete(['n', :o])
Cypher:
DELETE n, o

#set_props

Ruby:
.set_props('n = {name: "Brian"}')
Cypher:
SET n = {name: "Brian"}

Ruby:
.set_props(n: {name: 'Brian', age: 30})
Cypher:
SET n = {n_set_props}

Parameters: {:n_set_props=>{:name=>"Brian", :age=>30}}


#set

Ruby:
.set('n = {name: "Brian"}')
Cypher:
SET n = {name: "Brian"}

Ruby:
.set(n: {name: 'Brian', age: 30})
Cypher:
SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


Ruby:
.set(n: {name: 'Brian', age: 30}, o: {age: 29})
Cypher:
SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.`age` = {setter_o_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30, :setter_o_age=>29}


Ruby:
.set(n: {name: 'Brian', age: 30}).set_props('o.age = 29')
Cypher:
SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.age = 29

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


Ruby:
.set(n: :Label)
Cypher:
SET n:`Label`

Ruby:
.set(n: [:Label, 'Foo'])
Cypher:
SET n:`Label`, n:`Foo`

Ruby:
.set(n: nil)
Cypher:

#on_create_set

Ruby:
.on_create_set('n = {name: "Brian"}')
Cypher:
ON CREATE SET n = {name: "Brian"}

Ruby:
.on_create_set(n: {})
Cypher:

Ruby:
.on_create_set(n: {name: 'Brian', age: 30})
Cypher:
ON CREATE SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


Ruby:
.on_create_set(n: {name: 'Brian', age: 30}, o: {age: 29})
Cypher:
ON CREATE SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.`age` = {setter_o_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30, :setter_o_age=>29}


Ruby:
.on_create_set(n: {name: 'Brian', age: 30}).on_create_set('o.age = 29')
Cypher:
ON CREATE SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.age = 29

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


#on_match_set

Ruby:
.on_match_set('n = {name: "Brian"}')
Cypher:
ON MATCH SET n = {name: "Brian"}

Ruby:
.on_match_set(n: {})
Cypher:

Ruby:
.on_match_set(n: {name: 'Brian', age: 30})
Cypher:
ON MATCH SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


Ruby:
.on_match_set(n: {name: 'Brian', age: 30}, o: {age: 29})
Cypher:
ON MATCH SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.`age` = {setter_o_age}

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30, :setter_o_age=>29}


Ruby:
.on_match_set(n: {name: 'Brian', age: 30}).on_match_set('o.age = 29')
Cypher:
ON MATCH SET n.`name` = {setter_n_name}, n.`age` = {setter_n_age}, o.age = 29

Parameters: {:setter_n_name=>"Brian", :setter_n_age=>30}


#remove

Ruby:
.remove('n.prop')
Cypher:
REMOVE n.prop

Ruby:
.remove('n:American')
Cypher:
REMOVE n:American

Ruby:
.remove(n: 'prop')
Cypher:
REMOVE n.prop

Ruby:
.remove(n: :American)
Cypher:
REMOVE n:`American`

Ruby:
.remove(n: [:American, "prop"])
Cypher:
REMOVE n:`American`, n.prop

Ruby:
.remove(n: :American, o: 'prop')
Cypher:
REMOVE n:`American`, o.prop

Ruby:
.remove(n: ':prop')
Cypher:
REMOVE n:`prop`

#start

Ruby:
.start('r=node:nodes(name = "Brian")')
Cypher:
START r=node:nodes(name = "Brian")

Ruby:
.start(r: 'node:nodes(name = "Brian")')
Cypher:
START r = node:nodes(name = "Brian")

clause combinations

Ruby:
.match(q: Person).where('q.age > 30')
Cypher:
MATCH (q:`Person`) WHERE (q.age > 30)

Ruby:
.where('q.age > 30').match(q: Person)
Cypher:
MATCH (q:`Person`) WHERE (q.age > 30)

Ruby:
.where('q.age > 30').start('n').match(q: Person)
Cypher:
START n MATCH (q:`Person`) WHERE (q.age > 30)

Ruby:
.match(q: {age: 30}).set_props(q: {age: 31})
Cypher:
MATCH (q {age: {q_age}}) SET q = {q_set_props}

Parameters: {:q_age=>30, :q_set_props=>{:age=>31}}


Ruby:
.match(q: Person).with('count(q) AS count')
Cypher:
MATCH (q:`Person`) WITH count(q) AS count

Ruby:
.match(q: Person).with('count(q) AS count').where('count > 2')
Cypher:
MATCH (q:`Person`) WITH count(q) AS count WHERE (count > 2)

Ruby:
.match(q: Person).with(count: 'count(q)').where('count > 2').with(new_count: 'count + 5')
Cypher:
MATCH (q:`Person`) WITH count(q) AS count WHERE (count > 2) WITH count + 5 AS new_count

Ruby:
.match(q: Person).match('r:Car').break.match('(p: Person)-->q')
Cypher:
MATCH (q:`Person`), r:Car MATCH (p: Person)-->q

Ruby:
.match(q: Person).break.match('r:Car').break.match('(p: Person)-->q')
Cypher:
MATCH (q:`Person`) MATCH r:Car MATCH (p: Person)-->q

Ruby:
.match(q: Person).match('r:Car').break.break.match('(p: Person)-->q')
Cypher:
MATCH (q:`Person`), r:Car MATCH (p: Person)-->q

Ruby:
.with(:a).order(a: {name: :desc}).where(a: {name: 'Foo'})
Cypher:
WITH a ORDER BY a.name DESC WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo"}


Ruby:
.with(:a).limit(2).where(a: {name: 'Foo'})
Cypher:
WITH a LIMIT {limit_2} WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo", :limit_2=>2}


Ruby:
.with(:a).order(a: {name: :desc}).limit(2).where(a: {name: 'Foo'})
Cypher:
WITH a ORDER BY a.name DESC LIMIT {limit_2} WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo", :limit_2=>2}


Ruby:
.order(a: {name: :desc}).with(:a).where(a: {name: 'Foo'})
Cypher:
WITH a ORDER BY a.name DESC WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo"}


Ruby:
.limit(2).with(:a).where(a: {name: 'Foo'})
Cypher:
WITH a LIMIT {limit_2} WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo", :limit_2=>2}


Ruby:
.order(a: {name: :desc}).limit(2).with(:a).where(a: {name: 'Foo'})
Cypher:
WITH a ORDER BY a.name DESC LIMIT {limit_2} WHERE (a.name = {a_name})

Parameters: {:a_name=>"Foo", :limit_2=>2}


Ruby:
.match(q: Person).where('q.age = {age}').params(age: 15)
Cypher:
MATCH (q:`Person`) WHERE (q.age = {age})

Parameters: {:age=>15}