Skip to content

Latest commit

 

History

History
2332 lines (1297 loc) · 31 KB

QueryClauseMethods.rst

File metadata and controls

2332 lines (1297 loc) · 31 KB

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:

a_session.query
# The current session for `ActiveNode` / `ActiveRel` in the `neo4j` gem can be retrieved with `Neo4j::ActiveBase.current_session`

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', 'o--p')
Cypher
MATCH n--o, o--p

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.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_param})

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


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

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


Ruby
.where('(LOWER(str(q.name)) =~ ?)', '.*test.*')
Cypher
WHERE (LOWER(str(q.name)) =~ {question_mark_param})

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


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

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


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

Parameters: {:question_mark_param=>[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(name: /Brian.*/i).where(name: /Smith.*/i)
Cypher
WHERE (name =~ {name}) AND (name =~ {name2})

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


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_param})

Parameters: {:question_mark_param=>[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}


Ruby
.optional_match_nodes(var: node_object)
Cypher
OPTIONAL 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: :neo_id)
Cypher
ORDER BY ID(q)

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

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

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

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

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

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

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

Ruby
.order(q: [:neo_id, 'name desc'])
Cypher
ORDER BY ID(q), 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_3=>3, :limit_5=>5}


Ruby
.limit(nil)
Cypher

#skip

Ruby
.skip(5)
Cypher
SKIP {skip_5}

Parameters: {:skip_5=>5}


Ruby
.skip('5')
Cypher
SKIP {skip_5}

Parameters: {:skip_5=>5}


Ruby
.skip(5).skip(10)
Cypher
SKIP {skip_10}

Parameters: {:skip_5=>5, :skip_10=>10}


Ruby
.offset(6)
Cypher
SKIP {skip_6}

Parameters: {:skip_6=>6}


#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}


Ruby
.create(q: {:'Child:Person' => {age: 41, height: 70}})
Cypher
CREATE (q:`Child:Person` {age: {q_Child_Person_age}, height: {q_Child_Person_height}})

Parameters: {:q_Child_Person_age=>41, :q_Child_Person_height=>70}


Ruby
.create(:'Child:Person' => {age: 41, height: 70})
Cypher
CREATE (:`Child:Person` {age: {Child_Person_age}, height: {Child_Person_height}})

Parameters: {:Child_Person_age=>41, :Child_Person_height=>70}


Ruby
.create(q: {[:Child, :Person] => {age: 41, height: 70}})
Cypher
CREATE (q:`Child`:`Person` {age: {q_Child_Person_age}, height: {q_Child_Person_height}})

Parameters: {:q_Child_Person_age=>41, :q_Child_Person_height=>70}


Ruby
.create([:Child, :Person] => {age: 41, height: 70})
Cypher
CREATE (:`Child`:`Person` {age: {Child_Person_age}, height: {Child_Person_height}})

Parameters: {:Child_Person_age=>41, :Child_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(:Person).merge(:Thing)
Cypher
MERGE (:Person) MERGE (:Thing)

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

Ruby
.detach_delete('n')
Cypher
DETACH DELETE n

Ruby
.detach_delete(:n)
Cypher
DETACH DELETE n

Ruby
.detach_delete('n', :o)
Cypher
DETACH DELETE n, o

Ruby
.detach_delete(['n', :o])
Cypher
DETACH 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
.with('1 AS a').where(a: 1).limit(2)
Cypher
WITH 1 AS a WHERE (a = {a}) LIMIT {limit_2}

Parameters: {:a=>1, :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}