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: [:Person, "Animal"])
|
Cypher: | MATCH (n:`Person`:`Animal`)
|
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').match('o--p')
|
Cypher: |
|
#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('INDEX m:German(surname)').using('SCAN m:German')
|
Cypher: | USING INDEX m:German(surname) USING SCAN m:German
|
#where
Parameters: {:q_age=>30}
Ruby: | .where('q.age' => [30, 32, 34])
|
Cypher: |
|
Parameters: {:q_age=>[30, 32, 34]}
Ruby: | .where('q.age IN {age}', age: [30, 32, 34])
|
Cypher: |
|
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: |
|
Parameters: {:q_age=>[30, 32, 34]}
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.*"}
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('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: |
|
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(x: [1,3,5]).unwind('val as y')
|
Cypher: | UNWIND [1, 3, 5] AS x UNWIND val as y
|
#return
Ruby: | .return(q: [:name, :age], r: :grade)
|
Cypher: | RETURN q.name, q.age, r.grade
|
Ruby: | .return(q: [:neo_id, :prop])
|
Cypher: |
|
#order
Ruby: | .order('q.age', 'q.name DESC')
|
Cypher: | ORDER BY q.age, q.name DESC
|
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
Parameters: {:limit_3=>3}
Parameters: {:limit_3=>3}
Parameters: {:limit_5=>5}
#skip
Parameters: {:skip_5=>5}
Parameters: {:skip_5=>5}
Parameters: {:skip_10=>10}
Parameters: {:skip_6=>6}
#with
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
|
#create
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: |
|
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(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}
#set_props
Ruby: | .set_props('n = {name: "Brian"}')
|
Cypher: |
|
Ruby: | .set_props(n: {name: 'Brian', age: 30})
|
Cypher: |
|
Parameters: {:n_set_props=>{:name=>"Brian", :age=>30}}
#set
Ruby: | .set('n = {name: "Brian"}')
|
Cypher: |
|
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}
#on_create_set
Ruby: | .on_create_set('n = {name: "Brian"}')
|
Cypher: | ON CREATE SET n = {name: "Brian"}
|
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: {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: [:American, "prop"])
|
Cypher: | REMOVE n:`American`, n.prop
|
Ruby: | .remove(n: :American, o: 'prop')
|
Cypher: | REMOVE n:`American`, o.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}