Skip to content

Commit d23b153

Browse files
committed
fleshed out the sections a bit, examples need some updates still
1 parent 6401f14 commit d23b153

File tree

1 file changed

+279
-31
lines changed

1 file changed

+279
-31
lines changed
Lines changed: 279 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
= Sequential queries (`NEXT`)
22
:description: Information about how to use `NEXT` to construct sequential queries in Cypher.
3+
:table-caption!:
34
:page-role: new-2025.06
45

56
`NEXT` allows for linear composition of queries into a sequence of smaller, self-contained segments while making return values from one segment available in the next.
67

7-
`NEXT` has a number of benefits:
8+
`NEXT` has the following benefits:
89

910
* `NEXT` can improve the modularity and readability of complex queries.
10-
* `NEXT` reduces the need to rely on the xref:clauses/call.adoc[CALL] and xref:clauses/with.adoc[] clauses to construct complex queries.
11-
* `NEXT` improves the usability of xref:queries/composed-queries/conditional-queries.adoc[conditional] and xref:queries/composed-queries/combined-queries.adoc[UNION] queries.
11+
* `NEXT` can be used instead of xref:subqueries/call-subquery.adoc[] and the xref:clauses/with.adoc[] clause to construct complex queries.
12+
* `NEXT` can improve the usability of xref:queries/composed-queries/conditional-queries.adoc[conditional] and xref:queries/composed-queries/combined-queries.adoc[UNION] queries.
1213
1314
`NEXT` was introduced as part of Cypher's xref:appendix/gql-conformance/index.adoc[].
1415

@@ -19,59 +20,306 @@
1920

2021
The following graph is used for the examples on this page:
2122

22-
image::conditional_query_graph.svg[width="700",role="middle"]
23+
image::with_clause.svg[width="600",role="middle"]
2324

24-
To recreate the graph, run the following query against an empty Neo4j database:
25+
To recreate the graph, run the following query against an empty Neo4j database.
2526

2627
[source, cypher, role=test-setup]
2728
----
28-
CREATE (alice:Person {name:'Alice', age: 65}),
29-
(bob:Person {name: 'Bob', age: 25}),
30-
(charlie:Person {name: 'Charlie', age: 61}),
31-
(daniel:Person {name: 'Daniel', age: 39}),
32-
(eskil:Person {name: 'Eskil', age: 39}),
33-
(bob)-[:WORKS_FOR]->(alice),
34-
(alice)-[:WORKS_FOR]->(daniel),
35-
(charlie)-[:WORKS_FOR]->(daniel),
36-
(bob)-[:LOVES]->(eskil),
37-
(charlie)-[:LOVES]->(alice)
29+
CREATE (techCorp:Supplier {name: 'TechCorp', email: '[email protected]'}),
30+
(foodies:Supplier {name: 'Foodies Inc.', email: '[email protected]'}),
31+
32+
(laptop:Product {name: 'Laptop', price: 1000}),
33+
(phone:Product {name: 'Phone', price: 500}),
34+
(headphones:Product {name: 'Headphones', price: 250}),
35+
(chocolate:Product {name: 'Chocolate', price: 5}),
36+
(coffee:Product {name: 'Coffee', price: 10}),
37+
38+
(amir:Customer {firstName: 'Amir', lastName: 'Rahman', email: '[email protected]', discount: 0.1}),
39+
(keisha:Customer {firstName: 'Keisha', lastName: 'Nguyen', email: '[email protected]', discount: 0.2}),
40+
(mateo:Customer {firstName: 'Mateo', lastName: 'Ortega', email: '[email protected]', discount: 0.05}),
41+
(hannah:Customer {firstName: 'Hannah', lastName: 'Connor', email: '[email protected]', discount: 0.15}),
42+
(leila:Customer {firstName: 'Leila', lastName: 'Haddad', email: '[email protected]', discount: 0.1}),
43+
(niko:Customer {firstName: 'Niko', lastName: 'Petrov', email: '[email protected]', discount: 0.25}),
44+
(yusuf:Customer {firstName: 'Yusuf', lastName: 'Abdi', email: '[email protected]', discount: 0.1}),
45+
46+
(amir)-[:BUYS {date: date('2024-10-09')}]->(laptop),
47+
(amir)-[:BUYS {date: date('2025-01-10')}]->(chocolate),
48+
(keisha)-[:BUYS {date: date('2023-07-09')}]->(headphones),
49+
(mateo)-[:BUYS {date: date('2025-03-05')}]->(chocolate),
50+
(mateo)-[:BUYS {date: date('2025-03-05')}]->(coffee),
51+
(mateo)-[:BUYS {date: date('2024-04-11')}]->(laptop),
52+
(hannah)-[:BUYS {date: date('2023-12-11')}]->(coffee),
53+
(hannah)-[:BUYS {date: date('2024-06-02')}]->(headphones),
54+
(leila)-[:BUYS {date: date('2023-05-17')}]->(laptop),
55+
(niko)-[:BUYS {date: date('2025-02-27')}]->(phone),
56+
(niko)-[:BUYS {date: date('2024-08-23')}]->(headphones),
57+
(niko)-[:BUYS {date: date('2024-12-24')}]->(coffee),
58+
(yusuf)-[:BUYS {date: date('2024-12-24')}]->(chocolate),
59+
(yusuf)-[:BUYS {date: date('2025-01-02')}]->(laptop),
60+
61+
(techCorp)-[:SUPPLIES]->(laptop),
62+
(techCorp)-[:SUPPLIES]->(phone),
63+
(techCorp)-[:SUPPLIES]->(headphones),
64+
(foodies)-[:SUPPLIES]->(chocolate),
65+
(foodies)-[:SUPPLIES]->(coffee)
66+
----
67+
68+
69+
== Composing queries with `NEXT`
70+
71+
.`NEXT` syntax
72+
[source, cypher]
73+
----
74+
<Query1>
75+
76+
NEXT
77+
78+
<Query2>
79+
80+
NEXT
81+
82+
<Query3>
83+
----
84+
85+
86+
=== Passing values to subsequent queries
87+
88+
In the following example, `NEXT` passes the variable `customer` to the second query:
89+
90+
.Passing a variable to another query via `NEXT`
91+
====
92+
.Query
93+
[source, cypher]
3894
----
95+
MATCH (c:Customer)-[:BUYS]->(:Product {name: 'Chocolate'})
96+
RETURN c AS customer
97+
98+
NEXT
3999
100+
RETURN customer.firstName AS chocolateCustomer
101+
----
40102
41-
[[sequential-syntax]]
42-
== Syntax
103+
.Result
104+
[role="queryresult",options="header,footer",cols="1*<m"]
105+
|===
106+
| chocolateCustomer
43107
44-
Lorem ipsum.
108+
| "Amir"
109+
| "Mateo"
110+
| "Yusuf"
45111
112+
1+d|Rows: 3
113+
|===
114+
====
46115

47-
[[sequential-rules]]
48-
== Rules
49116

50-
Lorem ipsum.
117+
.Passing multiple variables to another query via `NEXT`
118+
====
119+
.Query
120+
[source, cypher]
121+
----
122+
MATCH (c:Customer)-[:BUYS]->(p:Product {name: 'Chocolate'})
123+
RETURN c AS customer, p AS product
124+
125+
NEXT
126+
127+
RETURN customer.firstName AS chocolateCustomer,
128+
product.price * (1 - customer.discount) AS chocolatePrice
51129
52-
.Not allowed: not aliasing returned expressions
53-
[source, cypher, role=test-fail]
54130
----
55-
WHEN true THEN RETURN 2
56-
ELSE RETURN 3
131+
132+
.Result
133+
[role="queryresult",options="header,footer",cols="2*<m"]
134+
|===
135+
| chocolateCustomer | chocolatePrice
136+
137+
| "Amir" | 4.5
138+
| "Mateo" | 4.75
139+
| "Yusuf" | 4.5
140+
141+
2+d|Rows: 3
142+
|===
143+
====
144+
145+
146+
147+
[NOTE]
148+
====
149+
Expressions in a `RETURN` clause must be aliased with an `AS` or a `LET` when they are followed by a `NEXT` clause.
150+
====
151+
152+
// is an example necessary? not a fan of negative examples in general
153+
154+
155+
== Interactions with `CALL` subqueries and `WITH`
156+
157+
You can use `NEXT` to rewrite queries containing `CALL` subqueries or a `WITH` clause.
158+
159+
.Rewriting a query with a `CALL` subquery
160+
====
161+
[cols="1,1"]
162+
|===
163+
a|
164+
.`CALL` subquery
165+
[source, cypher]
57166
----
167+
LET a = 1
168+
WITH a
58169
170+
CALL(*) {
171+
LET b = a + 1
172+
RETURN b
173+
UNION
174+
LET b = a + 2
175+
RETURN b
176+
}
177+
WITH a, b
59178
60-
== Using `NEXT` instead of `CALL`
179+
LET c = b + 1
180+
RETURN a, b, c
181+
----
182+
a|
183+
.`NEXT`
184+
[source, cypher]
185+
----
186+
LET a = 1
187+
RETURN a
61188
62-
Lorem ipsum.
189+
NEXT
63190
191+
LET b = a + 1
192+
RETURN a, b
193+
UNION
194+
LET b = a + 2
195+
RETURN a, b
64196
65-
== Using `NEXT` instead of `WITH`
197+
NEXT
66198
67-
Lorem ipsum.
199+
LET c = b + 1
200+
RETURN a, b, c
201+
----
202+
|===
203+
====
68204

69205

206+
207+
.Rewriting a `WITH` query
208+
====
209+
[cols="1,1"]
210+
|===
211+
a|
212+
.`WITH`
213+
[source, cypher]
214+
----
215+
LET a = 1
216+
WITH a
217+
LET b = a + 1
218+
WITH a, b
219+
LET c = a + b + 1
220+
WITH b, c
221+
LET d = b + c
222+
RETURN d
223+
----
224+
a|
225+
.`NEXT`
226+
[source, cypher]
227+
----
228+
LET a = 1
229+
RETURN a
230+
231+
NEXT
232+
233+
LET b = a + 1
234+
RETURN a, b
235+
236+
NEXT
237+
238+
LET c = a + b + 1
239+
RETURN b, c
240+
241+
NEXT
242+
243+
LET d = b + c
244+
RETURN d
245+
----
246+
|===
247+
====
248+
249+
Variables which are local to a query and which are not explicitly returned are not accessible by its subsequent query in the context of `NEXT`.
250+
This allows you to control variable scope similarly to what you can do with `WITH`, see xref:clauses/with.adoc#variable-scope[Control variables in scope].
251+
252+
[NOTE]
253+
====
254+
`NEXT` cannot be used inside a `CALL` subquery that uses the (deprecated) xref:subqueries/call-subquery.adoc#importing-with[importing `WITH`] syntax.
255+
====
256+
70257
== Interactions with conditional queries
71258

72-
Lorem ipsum.
259+
// use example with the example data set instead
260+
261+
.`NEXT` in a conditional query
262+
====
263+
.Query
264+
[source, cypher]
265+
----
266+
MATCH (n)
267+
RETURN n
268+
269+
NEXT
270+
271+
WHEN n.x > 2 THEN
272+
RETURN "large number" AS msg
273+
WHEN n.x > 1 THEN
274+
RETURN "small number" AS msg
275+
ELSE
276+
RETURN "tiny number" AS msg
277+
278+
----
279+
280+
.Result
281+
[role="queryresult",options="header,footer",cols="1*<m"]
282+
|===
283+
| chocolateCustomer
284+
285+
| "Amir"
286+
| "Mateo"
287+
| "Yusuf"
288+
289+
1+d|Rows: 3
290+
|===
291+
====
73292

74293

75294
== Interactions with `UNION` queries
76295

77-
Lorem ipsum.
296+
// use example with the example data set instead
297+
298+
.`NEXT` in a query using `UNION`
299+
====
300+
.Query
301+
[source, cypher]
302+
----
303+
RETURN 1 AS a
304+
UNION
305+
RETURN 2 AS a
306+
307+
NEXT
308+
309+
RETURN a, a + 1 AS b
310+
UNION
311+
RETURN a, a + 2 AS b
312+
----
313+
314+
.Result
315+
[role="queryresult",options="header,footer",cols="1*<m"]
316+
|===
317+
| chocolateCustomer
318+
319+
| "Amir"
320+
| "Mateo"
321+
| "Yusuf"
322+
323+
1+d|Rows: 3
324+
|===
325+
====

0 commit comments

Comments
 (0)