Skip to content

Commit 2991f8e

Browse files
more updates
1 parent 5c4df40 commit 2991f8e

File tree

1 file changed

+152
-43
lines changed

1 file changed

+152
-43
lines changed

modules/ROOT/pages/clauses/match.adoc

Lines changed: 152 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/ascii
33

44
= MATCH
55

6-
The `MATCH` clause allows you to specify the patterns Neo4j will search for in the database.
6+
The `MATCH` clause enables you to define specific patterns that the database will search for within its graph structure.
7+
The `MATCH` clause can specify the nodes, relationships, and properties in a pattern, allowing for queries that traverse the graph to retrieve relevant data.
78

89
[[match-example-graph]]
910
== Example graph
@@ -36,9 +37,9 @@ CREATE (charlie:Person {name: 'Charlie Sheen'}),
3637
[[find-nodes]]
3738
== Find nodes
3839

40+
The `MATCH` clause allows you to specify node patterns of varying complexity to retrieve from a graph.
3941
For more information about finding node patterns, see xref:patterns/fixed-length-patterns#node-patterns[Patterns -> Node patterns].
4042

41-
4243
[[find-all-nodes]]
4344
=== Find all nodes
4445

@@ -110,32 +111,52 @@ RETURN n.name AS name, n.title AS title
110111
2+|Rows: 7
111112
|===
112113

114+
.Node pattern using the `AND` (`&`) and negation (`!`) label expression
115+
[source, cypher]
116+
----
117+
MATCH (n:!Director&!Movie)
118+
RETURN labels(n) AS label, count(n) AS labelCount
119+
----
120+
121+
[NOTE]
122+
The above query uses the xref:functions/list.adoc#functions-labels[`labels()`] and xref:functions/aggregating.adoc#functions-count[`count()`] functions.
123+
124+
.Result
125+
[role="queryresult",options="header,footer",cols="2*<m"]
126+
|===
127+
| label | labelCount
128+
| ["Person"] | 5
129+
2+|Rows: 1
130+
|===
131+
113132
For a full list of all label expressions supported by Cypher, see xref:patterns/reference.adoc#label-expressions[Patterns -> Label expressions].
114133

115134
[[find-relationships]]
116135
== Find relationships
117136

137+
The `MATCH` clause allows you to specify relationship patterns of varying complexity to retrieve from a graph.
138+
Unlike a node pattern, a relationship pattern cannot be used in a `MATCH` clause without node patterns at both ends.
139+
For more information about relationship patterns, see xref:patterns/fixed-length-patterns#relationship patterns[Patterns -> Relationship patterns].
140+
141+
[NOTE]
118142
Relationships will only be matched once inside a single pattern.
119143
Read more about this behavior in the section on xref::patterns/reference.adoc#graph-patterns-rules-relationship-uniqueness[relationship uniqueness].
120144

121-
For more information about relationship patterns, see xref:patterns/fixed-length-patterns#relationship patterns[Patterns -> Relationship patterns].
122-
123145
[[empty-relationship-patterns]]
124146
=== Empty relationship patterns
125147

126148
By applying `--`, a pattern will be matched for a relationship with any direction and without any filtering on relationship types or properties.
127-
When matching a relationship pattern, a node pattern `()` must be applied at both ends.
128149

129150
.Find connected nodes using an empty relationship pattern
130151
----
131152
MATCH (director {name: 'Oliver Stone'})--(n)
132-
RETURN n
153+
RETURN n AS connectedNodes
133154
----
134155

135156
.Result
136157
[source, role="queryresult",options="header,footer",cols="1*<m"]
137158
|===
138-
| n
159+
| connectedNodes
139160
| (:Movie {title: "Wall Street"})
140161
|===
141162

@@ -148,13 +169,13 @@ The direction of a relationship in a pattern is indicated by arrows: `-->` or `<
148169
[source, cypher]
149170
----
150171
MATCH (:Person {name: 'Oliver Stone'})-->(movie)
151-
RETURN movie.title
172+
RETURN movie.title AS movieTitle
152173
----
153174

154175
.Result
155176
[source, role="queryresult",options="header,footer",cols="1*<m"]
156177
|===
157-
| movie.title
178+
| movieTitle
158179
| "Wall Street"
159180
|Rows: 1
160181
|===
@@ -168,13 +189,16 @@ It is possible to introduce a variable to a pattern, either for filtering on rel
168189
[source, cypher]
169190
----
170191
MATCH (:Person {name: 'Oliver Stone'})-[r]->(movie)
171-
RETURN type(r)
192+
RETURN type(r) AS relType
172193
----
173194

195+
[NOTE]
196+
The above query uses the xref:functions/scalar.adoc#functions-type[`type()` function].
197+
174198
.Result
175199
[source, role="queryresult",options="header,footer",cols="1*<m"]
176200
|===
177-
| type(r)
201+
| relType
178202
| "DIRECTED"
179203
|Rows: 1
180204
|===
@@ -208,19 +232,19 @@ RETURN a, b
208232
[[match-on-relationship-type]]
209233
=== Filter on relationship types
210234

211-
When the relationship type to match on is known, it is possible to specify it by using a colon (`:`) before the relationship type.
235+
It is possible to specify the type of a relationship in a relationship pattern by using a colon (`:`) before the relationship type.
212236

213-
.Relationship pattern filtering on a relationship type
237+
.Relationship pattern filtering on the `ACTED_IN` relationship type
214238
[source, cypher]
215239
----
216-
MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
217-
RETURN actor.name
240+
MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
241+
RETURN actor.name AS actor
218242
----
219243

220244
.Result
221245
[source, role="queryresult",options="header,footer",cols="1*<m"]
222246
|===
223-
| actor.name
247+
| actor
224248
| "Michael Douglas"
225249
| "Martin Sheen"
226250
| "Charlie Sheen"
@@ -235,22 +259,24 @@ It is possible to match for a pattern containing one out of several relationship
235259
.Relationship pattern including either `ACTED_IN` or `DIRECTED` relationship types
236260
[source, cypher]
237261
----
238-
MATCH (wallstreet {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(person)
239-
RETURN person.name
262+
MATCH ( {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(person)
263+
RETURN person.name AS person
240264
----
241265

242266
.Result
243267
[role="queryresult",options="header,footer",cols="1*<m"]
244268
|===
245-
| person.name
269+
| person
246270
| "Oliver Stone"
247271
| "Michael Douglas"
248272
| "Martin Sheen"
249273
| "Charlie Sheen"
250274
|Rows: 4
251275
|===
252276

253-
[[multiple-rels]]
277+
As relationships have exactly one type each, `()-[:A&B]->()` will never match a relationship.
278+
279+
[[multiple-relationships]]
254280
=== Find multiple relationships
255281

256282
A graph pattern can contain several relationship patterns.
@@ -259,36 +285,36 @@ A graph pattern can contain several relationship patterns.
259285
[source, cypher]
260286
----
261287
MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
262-
RETURN movie.title, director.name
288+
RETURN movie.title AS movieTitle, director.name AS director
263289
----
264290

265291
.Result
266292
[role="queryresult",options="header,footer",cols="2*<m"]
267293
|===
268-
| movie.title | director.name
294+
| movieTitle | director
269295
| "Wall Street" | "Oliver Stone"
270296
2+|Rows: 1
271297
|===
272298

273-
[[match-where-predicates]]
299+
[[where-predicates]]
274300
== MATCH with WHERE predicates
275301

276-
The MATCH clause is often paired with a `WHERE` sub-clause, which adds predicates to refine the patterns, making them more specific.
302+
The `MATCH` clause is often paired with a `WHERE` sub-clause, which adds predicates to refine the patterns, making them more specific.
277303
These predicates are part of the pattern itself, not just filters applied after matching.
278304
Thus, the `WHERE` clause should always be placed with its corresponding `MATCH` clause.
279305

280-
.Basic containing `WHERE` predicate
306+
.Simple `WHERE` predicate
281307
[source, cypher]
282308
----
283309
MATCH (charlie:Person)-[:ACTED_IN]->(movie:Movie)
284310
WHERE charlie.name = 'Charlie Sheen'
285-
RETURN movie.title
311+
RETURN movie.title AS movieTitle
286312
----
287313

288314
.Result
289315
[role="queryresult",options="header,footer",cols="1*<m"]
290316
|===
291-
| movie.title
317+
| movieTitle
292318
| "Wall Street"
293319
|Rows: 1
294320
|===
@@ -300,23 +326,64 @@ MATCH (martin:Person)-[:ACTED_IN]->(movie:Movie)
300326
WHERE martin.name = 'Martin Sheen' AND NOT EXISTS {
301327
MATCH (movie)<-[:DIRECTED]-(director:Person {name: 'Oliver Stone'})
302328
}
303-
RETURN movie.title
329+
RETURN movie.title AS movieTitle
304330
----
305331

332+
[NOTE]
333+
The above query uses an xref:subqueries/existential.adoc[`EXISTS` subquery].
334+
306335
.Result
307336
[role="queryresult",options="header,footer",cols="1*<m"]
308337
|===
309-
| movie.title
338+
| movieTitle
310339
| "The American President"
311340
|Rows: 1
312341
|===
313342

314343
For more information, see the xref:clauses/where.adoc[`WHERE`] page.
315344

345+
[[parameters]]
346+
== MATCH with parameters
347+
348+
The `MATCH` clause can be used with parameters.
349+
350+
.Parameters
351+
[source, parameters]
352+
----
353+
{
354+
"movieTitle": "Wall Street",
355+
"actorRole": "Fox"
356+
}
357+
----
358+
359+
.Find nodes using paramters
360+
[source, cypher]
361+
----
362+
MATCH (:Movie {title: $movieTitle})<-[r:ACTED_IN]-(p:Person)
363+
WHERE r.role CONTAINS $actorRole
364+
RETURN p.name AS actor, r.role AS role
365+
----
366+
367+
[NOTE]
368+
The above query uses the xref:syntax/operators.adoc#query-operator-comparison-string-specific[`CONTAINS` operator].
369+
370+
.Result
371+
[role="queryresult",options="header,footer",cols="2*<m"]
372+
|===
373+
| actor | role
374+
375+
| "Charlie Sheen" | "Bud Fox"
376+
| "Martin Sheen" | "Carl Fox"
377+
378+
2+|Rows: 2
379+
|===
380+
381+
For more information about how to set parameters, see xref:syntax/parameters.adoc[Syntax -> Parameters].
382+
316383
[[find-paths]]
317384
== Find paths
318385

319-
The `MATCH` clause can also be used to bind paths to variables.
386+
The `MATCH` clause can also be used to bind whole paths to variables.
320387

321388
.Find all paths matching a pattern
322389
[source, cypher]
@@ -356,26 +423,68 @@ RETURN path
356423
|Rows: 3
357424
|===
358425

359-
For more information about how `MATCH` is used to find patterns (including xref:patterns/variable-length-patterns.adoc#quantified-path-patterns[quantified path patterns], xref:patterns/variable-length-patterns.adoc#quantified-relationships[quantified relationships], and xref:patterns/shortest-paths.adoc[shortest paths]), see the section on xref::patterns/index.adoc[Patterns].
426+
For more information about how `MATCH` is used to find patterns of varying complexity (including xref:patterns/variable-length-patterns.adoc#quantified-path-patterns[quantified path patterns], xref:patterns/variable-length-patterns.adoc#quantified-relationships[quantified relationships], and the xref:patterns/shortest-paths.adoc[shortest paths] between nodes), see the section on xref::patterns/index.adoc[Patterns].
360427

361428
== Multiple MATCH clauses, the WITH clause, and clause composition
362429

363-
In Cypher, the output of a clause creates a new state of the graph, and a new table of intermediate results which serves as the input of the next clause.
364-
The first clause takes as input the state of the graph before the query and an empty table of intermediate results.
365-
The output of the last clause is the result of the query.
430+
In Cypher, a query’s behavior is defined by its clauses.
431+
Each clause takes the current graph state and a table of intermediate results, processes them, and passes the updated graph state and results to the next clause.
432+
The first clause starts with the graph's initial state and an empty table, while the final clause produces the query's result.
366433

434+
.Chaining consecutive `MATCH` clauses
435+
[source, cypher]
436+
----
437+
MATCH (:Person {name: 'Martin Sheen'})-[:ACTED_IN]->(movie:Movie) // <1>
438+
MATCH (director:Person)-[:DIRECTED]->(movie) // <2>
439+
RETURN director.name AS director, movie.title AS movieTitle
440+
----
441+
<1> The result of the first `MATCH` clause is the variable `movie` which holds all the `Movies` that `Martin Sheen` has `ACTED_IN`.
442+
<2> The second `MATCH` clause uses the `movie` variable to find any `Person` node with a `DIRECTED` relationship to those `Movie` nodes that `Martin Sheen` has `ACTED_IN`.
367443

368-
In Cypher, each clause has as input the state of the graph and a table of intermediate results
369-
Each clause has as input the state of the graph and a table of intermediate results consisting of the current variables. The output of a clause is a new state of the graph and a new table of intermediate results, serving as input to the next clause. The first clause takes as input the state of the graph before the query and an empty table of intermediate results. The output of the last clause is the result of the query.
444+
.Result
445+
[role="queryresult",options="header,footer",cols="2*<m"]
446+
|===
447+
| director | movieTitle
448+
449+
| "Oliver Stone" | "Wall Street"
450+
| "Rob Reiner" | "The American President"
370451

371-
MATCH (martin:Person {name: 'Martin Sheen'})-[:ACTED_IN]->(movie:Movie)
372-
WITH movie // Pass the movie variable to the next part of the query
373-
MATCH (director:Person)-[:DIRECTED]->(movie)
374-
RETURN director.name AS Director, movie.title AS MovieTitle
452+
2+d| Rows: 2
453+
|===
375454

455+
A variable can be implicitly carried over to the following clause by being referenced in another operation.
456+
A variable can also be explicitly passed to the following clause using the `WITH` clause.
457+
If a variable is neither implicitly nor explicitly carried over, it will be discarded and unavailable for reference later in the query.
376458

377-
== MATCH with parameters
459+
.Using `WITH` and multiple `MATCH` clauses
460+
[source, cypher]
461+
----
462+
MATCH (actors:Person)-[:ACTED_IN]->(movies:Movie) // <1>
463+
WITH actors, count(movies) AS movieCount // <2>
464+
ORDER BY movieCount DESC
465+
LIMIT 1 // <3>
466+
MATCH (actors)-[:ACTED_IN]->(movies) // <4>
467+
RETURN actors.name AS actor, movieCount, collect(movies.title) AS movies
468+
----
469+
<1> The `Person` and `Movie` nodes matched in this step are stored in variables.
470+
which are then passed on to the second row of the query.
471+
<2> The `movie` variable is here implicitly imported by its occurrence in the `count()` function.
472+
The `WITH` clause explicitly imports the `actors` variable.
473+
<3> An xref:clauses/order-by.adoc[`ORDER BY`] clause orders the results by `movieCount` in descending order, ensuring that the `Person` with the highest number of movies appears at the top, and xref:clauses/limit.adoc[`LIMIT] 1` ensures that all other `Person` nodes are discarded.
474+
<4> The second MATCH clause finds all `Movie` nodes associated with the `Person` nodes currently bound to the `actors` variable.
475+
476+
[NOTE]
477+
The above query uses the xref:functions/aggregating.adoc#functions-collect[`collect()` function].
478+
479+
.Result
480+
[role="queryresult",options="header,footer",cols="3*<m"]
481+
|===
482+
| actor | movieCount | movies
483+
484+
| "Martin Sheen" | 2 | ["Wall Street", "The American President"]
485+
3+d| Rows: 1
486+
487+
|===
378488

379-
:param movieTitle => 'Wall Street';
380-
MATCH (movie:Movie {title: $movieTitle})
489+
For more information about how Cypher queries work, see xref:clauses/clause-composition.adoc[].
381490

0 commit comments

Comments
 (0)