Overview
The NEXT
statement allows you to chain multiple statements to compose an advanced linear statement.
The query containing the NEXT
statement only returns the final table constructed by the last RETURN
statement.
<next statement> ::= "NEXT" [ <yield clause> ] <statement>
<statement> ::= <linear statement> | <composite query statement>
<linear statement> ::= { <simple statement>... } <result statement>
<simple statement> ::=
<insert statement>
| <set statement>
| <delete statement>
| <match statement>
| <filter statement>
| <let statement>
| <for statement>
| <order by statement>
| <limit statement>
| <skip statement>
| <call statement>
<result statement> ::=
<return statement> [ <order by statement> ] [ <skip statement> ] [ <limit statement> ]
Details
- There must be a
RETURN
statement beforeNEXT
to pass variables that can be referenced in the first statement afterNEXT
. - The
YIELD
clause can be used to select and rename variables to allow exposure in subsequent parts of the query.
Example Graph
The following examples run against this graph:
To create this graph, run the following query against an empty graph:
INSERT (rowlock:User {_id: 'U01', name: 'rowlock'}),
(brainy:User {_id: 'U02', name: 'Brainy'}),
(purplechalk:User {_id: 'U03', name: 'purplechalk'}),
(mochaeach:User {_id: 'U04', name: 'mochaeach'}),
(lionbower:User {_id: 'U05', name: 'lionbower'}),
(c01:Club {_id: 'C01'}),
(c02:Club {_id: 'C02'}),
(rowlock)-[:Follows]->(brainy),
(mochaeach)-[:Follows]->(brainy),
(purplechalk)-[:Follows]->(mochaeach),
(purplechalk)-[:Follows]->(lionbower),
(brainy)-[:Joins {memberNo: 1}]->(c01),
(lionbower)-[:Joins {memberNo: 2}]->(c01),
(mochaeach)-[:Joins {memberNo: 9}]->(c02)
Basic Usage
This query returns users who are followed by U03
while also members of C01
:
MATCH ({_id: "C01"})<-[:Joins]-(u1:User)
RETURN u1
NEXT
MATCH ({_id: "U03"})-[:Follows]->(u2:User)
WHERE u2 = u1
RETURN u2
Result: u2
_id | _uuid | schema | values |
---|---|---|---|
U05 | Sys-gen | User | {name: "lionbower"} |
If you attempt to use a FILTER
statement to check the equivalence of u2
and u1
, the query will throw an error because u1
is not in scope within the FILTER
statement:
MATCH ({_id: "C01"})<-[:Joins]-(u1:User)
RETURN u1
NEXT
MATCH ({_id: "U03"})-[:Follows]->(u2:User)
FILTER u2 = u1
RETURN u2
To address the scoping issue and ensure u1
is available in the subsequent query block, you can use the YIELD
clause in the MATCH
statement. This renews the exposure of u1
for use in the following statements:
MATCH ({_id: "C01"})<-[:Joins]-(u1:User)
RETURN u1
NEXT
MATCH ({_id: "U03"})-[:Follows]->(u2:User) YIELD u1, u2
FILTER u2 = u1
RETURN u2
Using Grouped Result
This query returns the names of users who joined the club with the maximum members:
MATCH (c:Club)<-[:Joins]-()
RETURN c, count(c) AS cnt GROUP BY c
ORDER BY cnt DESC LIMIT 1
NEXT
MATCH (c)<-[:Joins]-(u)
RETURN collect_list(u.name)
Result:
collect_list(u.name) |
---|
["Brainy","lionbower"] |
Using Aggregated Result
This query inserts a new Joins
edge from U01
to C01
and sets the memberNo
property to the next highest value:
MATCH ({_id: "C01"})<-[e1:Joins]-()
RETURN max(e1.memberNo) AS maxNo
NEXT
MATCH (u {_id: "U01"}), (c {_id: "C01"})
INSERT (c)<-[e2:Joins {memberNo: maxNo + 1}]-(u)
RETURN e2
Result: e2
_uuid |
_from |
_to |
_from_uuid |
_to_uuid |
schema |
values |
---|---|---|---|---|---|---|
Sys-gen | U01 | C01 | UUID of U01 | UUID of C01 | Joins | {memberNo: 3} |
NEXT YIELD
This query finds clubs joined by users followed by the user purplechalk
:
LET name = "purplechalk"
MATCH (:User {name: name})-[:Follows]->(u:User)
RETURN *
NEXT YIELD u
MATCH (u)-[:Joins]->(c:Club)
RETURN u.name, c._id
Result:
u.name | c._id |
---|---|
mochaeach | C02 |
lionbower | C01 |