ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.8 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://neo4j.com/graphgists/getting-the-results-you-want/ |
| Last Crawled | 2026-03-20 09:50:35 (23 days ago) |
| First Indexed | 2021-06-09 13:26:24 (4 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Getting the Results You Want - graphgists |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | Let’s first get some data in to retrieve results from:
CREATE (matrix:Movie {title:"The Matrix",released:1997})
CREATE (cloudAtlas:Movie {title:"Cloud Atlas",released:2012})
CREATE (forrestGump:Movie {title:"Forrest Gump",released:1994})
CREATE (keanu:Person {name:"Keanu Reeves", born:1964})
CREATE (robert:Person {name:"Robert Zemeckis", born:1951})
CREATE (tom:Person {name:"Tom Hanks", born:1956})
CREATE (tom)-[:ACTED_IN {roles:["Forrest"]}]->(forrestGump)
CREATE (tom)-[:ACTED_IN {roles:['Zachry']} ]->(cloudAtlas)
CREATE (robert)-[:DIRECTED]->(forrestGump)
This is the data we will start out with:
Nodes created: 6
Relationships created: 3
Properties set: 14
Labels added: 6
Filtering Results
So far we’ve matched patterns in the graph and always returned all results we found.
Quite often there are conditions in play for what we want to see.
Similar to in
SQL
those filter conditions are expressed in a
WHERE
clause.
This clause allows to use any number of boolean expressions (predicates) combined with
AND
,
OR
,
XOR
and
NOT
.
The simplest predicates are comparisons, especially equality.
MATCH (m:Movie)
WHERE m.title = "The Matrix"
RETURN m
For equality on one or more properties, a more compact syntax can be used as well:
MATCH (m:Movie {title: "The Matrix"})
RETURN m
Other options are numeric comparisons, matching regular expressions and checking the existence of values within a collection.
The
WHERE
clause below includes a regular expression match, a greater than comparison and a test to see if a value exists in a collection.
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE p.name =~ "K.+"
OR m.released > 2000
OR "Neo" IN r.roles
RETURN p,r,m
One aspect that might be a little surprising is that you can even use patterns as predicates.
Where
MATCH
expands the number and shape of patterns matched, a pattern predicate restricts the current result set.
It only allows the paths to pass that satisfy the additional patterns as well (or
NOT
).
MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE NOT (p)-[:DIRECTED]->()
RETURN p,m
Here we find actors, because they sport an
ACTED_IN
relationship but then skip those that ever
DIRECTED
any movie.
There are also more advanced ways of filtering like collection-predicates which we will look at later on.
Returning Results
So far we’ve returned only nodes, relationships, or paths directly via their identifiers.
But the
RETURN
clause can actually return any number of expressions.
But what are actually expressions in Cypher?
The simplest expressions are literal values like numbers, strings and arrays as
[1,2,3]
, and maps like
{name:"Tom Hanks", born:1964, movies:["Forrest Gump", …​], count:13}
.
You can access individual properties of any node, relationship, or map with a dot-syntax like
n.name
.
Individual elements or slices of arrays can be retrieved with subscripts like
names[0]
or
movies[1..-1]
.
Each function evaluation like
length(array)
,
toInt("12")
,
substring("2014-07-01",0,4)
, or
coalesce(p.nickname,"n/a")
is also an expression.
Predicates that you’d use in
WHERE
count as boolean expressions.
Of course simpler expressions can be composed and concatenated to form more complex expressions.
By default the expression itself will be used as label for the column, in many cases you want to alias that with a more understandable name using
expression AS alias
.
You can later on refer to that column using its alias.
MATCH (p:Person)
RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, {name: p.name, label:head(labels(p))} AS person
If you’re interested in unique results you can use the
DISTINCT
keyword after
RETURN
to indicate that.
Aggregating Information
In many cases you want to aggregate or group the data that you encounter while traversing patterns in your graph.
In Cypher aggregation happens in the
RETURN
clause while computing your final results.
Many common aggregation functions are supported, e.g.
count
,
sum
,
avg
,
min
, and
max
, but there are several more.
Counting the number of people in your database could be achieved by this:
MATCH (:Person)
RETURN count(*) as people
Please note that
NULL
values are skipped during aggregation.
For aggregating only unique values use
DISTINCT
, like in
count(DISTINCT role)
.
Aggregation in Cypher just works.
You specify which result columns you want to aggregate and
Cypher will use all non-aggregated columns as grouping keys
.
Aggregation affects which data is still visible in ordering or later query parts.
To find out how often an actor and director worked together, you’d run this statement:
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
RETURN actor,director,count(*) as collaborations
Frequently you want to sort and paginate after aggregating a
count(x)
.
Ordering and Pagination
Ordering works like in other query languages, with an
ORDER BY expression [ASC|DESC]
clause.
The expression can be any expression discussed before as long as it is computable from the returned information.
So for instance if you return
person.name
you can still
ORDER BY person.age
as both are accessible from the
person
reference.
You cannot order by things that you can’t infer from the information you return.
This is especially important with aggregation and
DISTINCT
return values as both remove the visibility of data that is aggregated.
Pagination is a straightforward use of
SKIP {offset} LIMIT {count}
.
A common pattern is to aggregate for a count (score or frequency), order by it and only return the top-n entries.
For instance to find the most prolific actors you could do:
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN a,count(*) as appearances
ORDER BY appearances DESC
LIMIT 10;
Collecting Aggregation
The most helpful aggregation function is
collect
, which, as the name says, collects all aggregated values into a
real
array or list.
This comes very handy in many situations as you don’t loose the detail information while aggregating.
Collect is well suited for retrieving the typical parent-child structures, where one core entity (parent, root or head) is returned per row with all it’s dependent information in associated collections created with
collect
.
This means there’s no need to repeat the parent information per each child-row or even running 1+n statements to retrieve the parent and its children individually.
To retrieve the cast of each movie in our database you could use this statement:
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title as movie, collect(a.name) as cast, count(*) as actors
The lists created by collect can either be used from the client consuming the Cypher results or directly within a statement with any of the collection functions or predicates. |
| Markdown | [](https://neo4j.com/) [GraphGists](https://neo4j.com/graphgists/)
[Use Cases](https://neo4j.com/graphgists/)
[General Business](https://neo4j.com/graphgists/categories/general-business/)
[Data Analysis](https://neo4j.com/graphgists/categories/data-analysis/)
[Pop Culture](https://neo4j.com/graphgists/categories/pop-culture/)
[Network and IT Operations](https://neo4j.com/graphgists/categories/network-and-it-operations/)
[Holidays](https://neo4j.com/graphgists/categories/holidays/)
[GraphGist Challenge Entries](https://neo4j.com/graphgists/categories/graphgist-challenge/)
[Real-Time Recommendations](https://neo4j.com/graphgists/categories/real-time-recommendations/)
[Open Government Data and Politics](https://neo4j.com/graphgists/categories/open-government-data-and-politics/)
[Graph-Based Search](https://neo4j.com/graphgists/categories/graph-based-search/)
[Graph Gist How-tos](https://neo4j.com/graphgists/categories/graph-gist-how-tos/)
[Fraud Detection](https://neo4j.com/graphgists/categories/fraud-detection/)
[Investigative Journalism](https://neo4j.com/graphgists/categories/investigative-journalism/)
[Identity and Access Management](https://neo4j.com/graphgists/categories/identity-and-access-management/)
[Sports and Recreation](https://neo4j.com/graphgists/categories/sports-and-recreation/)
[Public Web APIs](https://neo4j.com/graphgists/categories/public-web-apis/)
[Master Data Management](https://neo4j.com/graphgists/categories/master-data-management/)
[Optimization](https://neo4j.com/graphgists/categories/optimization/)
[Industries](https://neo4j.com/graphgists/)
[Transportation and Logistics](https://neo4j.com/graphgists/categories/transportation-and-logistics/)
[Finance](https://neo4j.com/graphgists/categories/finance/)
[Retail](https://neo4j.com/graphgists/categories/retail/)
[Comp Sci and Programming](https://neo4j.com/graphgists/categories/computer-science-and-programming/)
[Science](https://neo4j.com/graphgists/categories/science/)
[Web & Social](https://neo4j.com/graphgists/categories/web-amp-social/)
[Sports and Recreation](https://neo4j.com/graphgists/categories/sports-and-gaming/)
[Health Care](https://neo4j.com/graphgists/categories/health-care-and-science/)
[Education](https://neo4j.com/graphgists/categories/education/)
[Docs](https://neo4j.com/docs/)
Neo4j DBMS
- [Getting Started](https://neo4j.com/docs/getting-started/current/)
- [Operations](https://neo4j.com/docs/operations-manual/current/)
- [Migration and Upgrade](https://neo4j.com/docs/migration-guide/current/)
- [Status Codes](https://neo4j.com/docs/status-codes/current/)
- [Java Reference](https://neo4j.com/docs/java-reference/current/)
- [Kerberos Add-on](https://neo4j.com/docs/kerberos-add-on/current/)
[Neo4j Aura](https://neo4j.com/docs/aura/)
Neo4j Tools
- [Neo4j Bloom](https://neo4j.com/docs/bloom-user-guide/current/)
- [Neo4j Browser](https://neo4j.com/docs/browser/)
- [Neo4j Data Importer](https://neo4j.com/docs/data-importer/current/)
- [Neo4j Desktop](https://neo4j.com/docs/desktop-manual/current/)
- [Neo4j Ops Manager](https://neo4j.com/docs/ops-manager/current/)
- [Neodash commercial](https://neo4j.com/docs/neodash-commercial/current/)
Neo4j Graph Data Science
- [Neo4j Graph Data Science Library](https://neo4j.com/docs/graph-data-science/current/)
- [Neo4j Graph Data Science Client](https://neo4j.com/docs/graph-data-science-client/current/)
Cypher Query Language
- [Cypher](https://neo4j.com/docs/cypher-manual/current/)
- [Cypher Cheat Sheet](https://neo4j.com/docs/cypher-cheat-sheet/current/)
- [APOC Library](https://neo4j.com/docs/apoc/current/)
Generative AI
- [Neo4j GraphRAG for Python](https://neo4j.com/docs/neo4j-graphrag-python/current/)
- [Embeddings and vector indexes tutorial](https://neo4j.com/docs/genai/tutorials/embeddings-vector-indexes/)
- [GenAI integrations](https://neo4j.com/docs/cypher-manual/current/genai-integrations/)
- [Vector search indexes](https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/vector-indexes/)
- [Vector search functions](https://neo4j.com/docs/cypher-manual/current/functions/vector/)
- [GraphQL vector index search documentation](https://neo4j.com/docs/graphql/5/directives/indexes-and-constraints/#_vector_index_search)
Create applications
- [Python Driver](https://neo4j.com/docs/python-manual/current/)
- [Go Driver](https://neo4j.com/docs/go-manual/current/)
- [Java Driver](https://neo4j.com/docs/java-manual/current/)
- [JDBC Driver](https://neo4j.com/docs/jdbc-manual/current/)
- [JavaScript Driver](https://neo4j.com/docs/javascript-manual/current/)
- [.Net Driver](https://neo4j.com/docs/dotnet-manual/current/)
- [Neo4j GraphQL Library](https://neo4j.com/docs/graphql-manual/current/)
- [Neo4j Visualization Library](https://neo4j.com/docs/nvl/current/)
- [OGM Library](https://neo4j.com/docs/ogm-manual/current/)
- [Spring Data Neo4j](https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#reference)
- [HTTP API](https://neo4j.com/docs/http-api/current/)
- [Neo4j Query API](https://neo4j.com/docs/query-api/current/)
- [Bolt](https://neo4j.com/docs/bolt/current/)
Connect data sources
- [Neo4j Connector for Apache Spark](https://neo4j.com/docs/spark/current/)
- [Neo4j Connector for Apache Kafka](https://neo4j.com/docs/kafka/)
- [Change Data Capture (CDC)](https://neo4j.com/docs/cdc/)
- [BigQuery to Neo4j](https://neo4j.com/docs/dataflow-bigquery/)
- [Google Cloud to Neo4j](https://neo4j.com/docs/dataflow-google-cloud/)
[Labs](https://neo4j.com/labs/)
[GenAI Ecosystem](https://neo4j.com/labs/genai-ecosystem/)
- [LLM Knowledge Graph Builder](https://neo4j.com/labs/genai-ecosystem/llm-graph-builder/)
- [Vector Index & Search](https://neo4j.com/labs/genai-ecosystem/vector-search/)
- [LangChain](https://neo4j.com/labs/genai-ecosystem/langchain/)
- [LangChain.js](https://neo4j.com/labs/genai-ecosystem/langchain-js/)
- [LlamaIndex](https://neo4j.com/labs/genai-ecosystem/llamaindex/)
- [Haystack](https://neo4j.com/labs/genai-ecosystem/haystack/)
- [DSPy](https://neo4j.com/labs/genai-ecosystem/dspy/)
**Developer Tools**
- [APOC Extended](https://neo4j.com/labs/apoc/)
- [Aura CLI](https://neo4j.com/labs/aura-cli/)
- [arrows.app](https://neo4j.com/labs/arrows/)
- [Cypher Workbench](https://neo4j.com/labs/cypher-workbench/)
- [ETL Tool](https://neo4j.com/labs/etl-tool/)
- [NeoDash](https://neo4j.com/labs/neodash/)
**Frameworks & Integrations**
- [Needle Starter Kit](https://neo4j.com/labs/neo4j-needle-starterkit/)
- [Neo4j Plugin for Liquibase](https://neo4j.com/labs/liquibase/)
- [Neo4j Migrations](https://neo4j.com/labs/neo4j-migrations/)
- [neomodel](https://neo4j.com/labs/neomodel/)
[RDF & Linked Data](https://neo4j.com/labs/neosemantics/)
- [Neosemantics (Java)](https://neo4j.com/labs/neosemantics/)
- [RDFLib-Neo4j (Python)](https://neo4j.com/labs/rdflib-neo4j/)
[Get Help](https://neo4j.com/developer/resources/)
[Community Forum](https://dev.neo4j.com/forum)
[Discord Chat](https://dev.neo4j.com/chat)
[Product Support](http://support.neo4j.com/)
[Neo4j Developer Blog](https://neo4j.com/blog/developer/)
[Neo4j Videos](https://neo4j.com/videos/)
[GraphAcademy](https://graphacademy.neo4j.com/?ref=docs-nav)
[Beginners Courses](https://graphacademy.neo4j.com/categories/beginners/?ref=docs-nav)
- [Neo4j Fundamentals](https://graphacademy.neo4j.com/courses/neo4j-fundamentals/?ref=docs-nav)
- [Cypher Fundamentals](https://graphacademy.neo4j.com/courses/cypher-fundamentals/?ref=docs-nav)
- [Importing Data Fundamentals](https://graphacademy.neo4j.com/courses/importing-fundamentals/?ref=docs-nav)
- [Importing CSV Data](https://graphacademy.neo4j.com/courses/importing-csv-data/?ref=docs-nav)
- [Graph Data Modeling](https://graphacademy.neo4j.com/courses/modeling-fundamentals/?ref=docs-nav)
[Data Scientist Courses](https://graphacademy.neo4j.com/categories/data-scientist/?ref=docs-nav)
- [Into to Graph Data Science](https://graphacademy.neo4j.com/courses/gds-product-introduction/?ref=docs-nav)
- [Graph Data Science Fundamentals](https://graphacademy.neo4j.com/courses/graph-data-science-fundamentals/?ref=docs-nav)
- [Path Finding](https://graphacademy.neo4j.com/courses/gds-shortest-paths/?ref=docs-nav)
[Generative AI Courses](https://graphacademy.neo4j.com/categories/llms/?ref=docs-nav)
- [Neo4j & LLM Fundamentals](https://graphacademy.neo4j.com/courses/llm-fundamentals/?ref=docs-nav)
- [Vector Indexes & Unstructured Data](https://graphacademy.neo4j.com/courses/llm-vectors-unstructured/?ref=docs-nav)
- [Build a Chatbot with Python](https://graphacademy.neo4j.com/courses/llm-chatbot-python/?ref=docs-nav)
- [Build a Chatbot with TypeScript](https://graphacademy.neo4j.com/courses/llm-chatbot-typescript/?ref=docs-nav)
[Neo4j Certification](https://graphacademy.neo4j.com/certification/?ref=docs-nav)
- [Neo4j Certified Professional](https://graphacademy.neo4j.com/certifications/neo4j-certification/?ref=docs-nav)
- [Neo4j Graph Data Science Certification](https://graphacademy.neo4j.com/certifications/gds-certification/?ref=docs-nav)
[Get Started Free](https://console.neo4j.io/?ref=docs-nav-get-started)
[Search](https://neo4j.com/graphgists/getting-the-results-you-want/#search)
## GraphGists
# Getting the Results You Want
Author
whatSocks
Industries
[Transportation and Logistics](https://neo4j.com/graphgists/categories/transportation-and-logistics/) [Finance](https://neo4j.com/graphgists/categories/finance/) [Retail](https://neo4j.com/graphgists/categories/retail/) [Comp Sci and Programming](https://neo4j.com/graphgists/categories/computer-science-and-programming/) [Science](https://neo4j.com/graphgists/categories/science/) [Web & Social](https://neo4j.com/graphgists/categories/web-amp-social/) [Sports and Recreation](https://neo4j.com/graphgists/categories/sports-and-gaming/) [Health Care](https://neo4j.com/graphgists/categories/health-care-and-science/) [Education](https://neo4j.com/graphgists/categories/education/)
Use cases
[Graph Gist How-tos](https://neo4j.com/graphgists/categories/graph-gist-how-tos/)
- [Show source](https://portal.graphgist.org/graph_gists/getting-the-results-you-want/source)
- [Download as Jupyter Notebook](https://neo4j.com/graphgists/_attachments/getting-the-results-you-want.ipynb)
- Open in Neo4j Browser
Connection URL
[Open]()
Let’s first get some data in to retrieve results from:
```
CREATE (matrix:Movie {title:"The Matrix",released:1997})
CREATE (cloudAtlas:Movie {title:"Cloud Atlas",released:2012})
CREATE (forrestGump:Movie {title:"Forrest Gump",released:1994})
CREATE (keanu:Person {name:"Keanu Reeves", born:1964})
CREATE (robert:Person {name:"Robert Zemeckis", born:1951})
CREATE (tom:Person {name:"Tom Hanks", born:1956})
CREATE (tom)-[:ACTED_IN {roles:["Forrest"]}]->(forrestGump)
CREATE (tom)-[:ACTED_IN {roles:['Zachry']} ]->(cloudAtlas)
CREATE (robert)-[:DIRECTED]->(forrestGump)
```
This is the data we will start out with:
```
Nodes created: 6
Relationships created: 3
Properties set: 14
Labels added: 6
```
# Filtering Results
So far we’ve matched patterns in the graph and always returned all results we found. Quite often there are conditions in play for what we want to see. Similar to in *SQL* those filter conditions are expressed in a `WHERE` clause. This clause allows to use any number of boolean expressions (predicates) combined with `AND`, `OR`, `XOR` and `NOT`. The simplest predicates are comparisons, especially equality.
```
MATCH (m:Movie)
WHERE m.title = "The Matrix"
RETURN m
```
For equality on one or more properties, a more compact syntax can be used as well:
```
MATCH (m:Movie {title: "The Matrix"})
RETURN m
```
Other options are numeric comparisons, matching regular expressions and checking the existence of values within a collection.
The `WHERE` clause below includes a regular expression match, a greater than comparison and a test to see if a value exists in a collection.
```
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE p.name =~ "K.+"
OR m.released > 2000
OR "Neo" IN r.roles
RETURN p,r,m
```
One aspect that might be a little surprising is that you can even use patterns as predicates. Where `MATCH` expands the number and shape of patterns matched, a pattern predicate restricts the current result set. It only allows the paths to pass that satisfy the additional patterns as well (or `NOT`).
```
MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE NOT (p)-[:DIRECTED]->()
RETURN p,m
```
Here we find actors, because they sport an `ACTED_IN` relationship but then skip those that ever `DIRECTED` any movie.
There are also more advanced ways of filtering like collection-predicates which we will look at later on.
# Returning Results
So far we’ve returned only nodes, relationships, or paths directly via their identifiers. But the `RETURN` clause can actually return any number of expressions. But what are actually expressions in Cypher?
The simplest expressions are literal values like numbers, strings and arrays as `[1,2,3]`, and maps like `{name:"Tom Hanks", born:1964, movies:["Forrest Gump", …​], count:13}`. You can access individual properties of any node, relationship, or map with a dot-syntax like `n.name`. Individual elements or slices of arrays can be retrieved with subscripts like `names[0]` or `movies[1..-1]`. Each function evaluation like `length(array)`, `toInt("12")`, `substring("2014-07-01",0,4)`, or `coalesce(p.nickname,"n/a")` is also an expression.
Predicates that you’d use in `WHERE` count as boolean expressions.
Of course simpler expressions can be composed and concatenated to form more complex expressions.
By default the expression itself will be used as label for the column, in many cases you want to alias that with a more understandable name using `expression AS alias`. You can later on refer to that column using its alias.
```
MATCH (p:Person)
RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, {name: p.name, label:head(labels(p))} AS person
```
If you’re interested in unique results you can use the `DISTINCT` keyword after `RETURN` to indicate that.
# Aggregating Information
In many cases you want to aggregate or group the data that you encounter while traversing patterns in your graph. In Cypher aggregation happens in the `RETURN` clause while computing your final results. Many common aggregation functions are supported, e.g. `count`, `sum`, `avg`, `min`, and `max`, but there are several more.
Counting the number of people in your database could be achieved by this:
```
MATCH (:Person)
RETURN count(*) as people
```
Please note that `NULL` values are skipped during aggregation. For aggregating only unique values use `DISTINCT`, like in `count(DISTINCT role)`.
Aggregation in Cypher just works. You specify which result columns you want to aggregate and *Cypher will use all non-aggregated columns as grouping keys*.
Aggregation affects which data is still visible in ordering or later query parts.
To find out how often an actor and director worked together, you’d run this statement:
```
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
RETURN actor,director,count(*) as collaborations
```
Frequently you want to sort and paginate after aggregating a `count(x)`.
# Ordering and Pagination
Ordering works like in other query languages, with an `ORDER BY expression [ASC|DESC]` clause. The expression can be any expression discussed before as long as it is computable from the returned information.
So for instance if you return `person.name` you can still `ORDER BY person.age` as both are accessible from the `person` reference. You cannot order by things that you can’t infer from the information you return. This is especially important with aggregation and `DISTINCT` return values as both remove the visibility of data that is aggregated.
Pagination is a straightforward use of `SKIP {offset} LIMIT {count}`.
A common pattern is to aggregate for a count (score or frequency), order by it and only return the top-n entries.
For instance to find the most prolific actors you could do:
```
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN a,count(*) as appearances
ORDER BY appearances DESC
LIMIT 10;
```
# Collecting Aggregation
The most helpful aggregation function is `collect`, which, as the name says, collects all aggregated values into a *real* array or list. This comes very handy in many situations as you don’t loose the detail information while aggregating.
Collect is well suited for retrieving the typical parent-child structures, where one core entity (parent, root or head) is returned per row with all it’s dependent information in associated collections created with `collect`. This means there’s no need to repeat the parent information per each child-row or even running 1+n statements to retrieve the parent and its children individually.
To retrieve the cast of each movie in our database you could use this statement:
```
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title as movie, collect(a.name) as cast, count(*) as actors
```
The lists created by collect can either be used from the client consuming the Cypher results or directly within a statement with any of the collection functions or predicates.
**Is this page helpful?**
## Learn
- [Sandbox](https://neo4j.com/sandbox/?ref=developer-footer)
- [Neo4j Community Site](https://community.neo4j.com/?ref=developer-footer)
- [Neo4j Developer Blog](https://medium.com/neo4j)
- [Neo4j Videos](https://www.youtube.com/neo4j)
- [GraphAcademy](https://neo4j.com/graphacademy/?ref=developer-footer)
- [Neo4j Labs](https://neo4j.com/labs/?ref=developer-footer)
## Social
- [Twitter](https://twitter.com/neo4j)
- [Meetups](https://www.meetup.com/Neo4j-Online-Meetup/)
- [Github](https://github.com/neo4j/neo4j)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/neo4j)
- [Want to Speak?](https://docs.google.com/forms/d/e/1FAIpQLSdEcNnMruES5iwvOVYovmS1D_P1ZL_HdUOitFrwrvruv5PZvA/viewform)
## [Contact Us →](https://neo4j.com/contact-us/?ref=footer)
- US: 1-855-636-4532
- Sweden +46 171 480 113
- UK: +44 20 3868 3223
- France: +33 (0) 1 88 46 13 20
© 2026 Neo4j, Inc.
[Terms](https://neo4j.com/terms/) \| [Privacy](https://neo4j.com/privacy-policy/) \| [Sitemap](https://neo4j.com/sitemap/)
Neo4j®, Neo Technology®, Cypher®, Neo4j® Bloom™ and Neo4j® Aura™ are registered trademarks of Neo4j, Inc. All other marks are owned by their respective companies. |
| Readable Markdown | Let’s first get some data in to retrieve results from:
```
CREATE (matrix:Movie {title:"The Matrix",released:1997})
CREATE (cloudAtlas:Movie {title:"Cloud Atlas",released:2012})
CREATE (forrestGump:Movie {title:"Forrest Gump",released:1994})
CREATE (keanu:Person {name:"Keanu Reeves", born:1964})
CREATE (robert:Person {name:"Robert Zemeckis", born:1951})
CREATE (tom:Person {name:"Tom Hanks", born:1956})
CREATE (tom)-[:ACTED_IN {roles:["Forrest"]}]->(forrestGump)
CREATE (tom)-[:ACTED_IN {roles:['Zachry']} ]->(cloudAtlas)
CREATE (robert)-[:DIRECTED]->(forrestGump)
```
This is the data we will start out with:
```
Nodes created: 6
Relationships created: 3
Properties set: 14
Labels added: 6
```
## Filtering Results
So far we’ve matched patterns in the graph and always returned all results we found. Quite often there are conditions in play for what we want to see. Similar to in *SQL* those filter conditions are expressed in a `WHERE` clause. This clause allows to use any number of boolean expressions (predicates) combined with `AND`, `OR`, `XOR` and `NOT`. The simplest predicates are comparisons, especially equality.
```
MATCH (m:Movie)
WHERE m.title = "The Matrix"
RETURN m
```
For equality on one or more properties, a more compact syntax can be used as well:
```
MATCH (m:Movie {title: "The Matrix"})
RETURN m
```
Other options are numeric comparisons, matching regular expressions and checking the existence of values within a collection.
The `WHERE` clause below includes a regular expression match, a greater than comparison and a test to see if a value exists in a collection.
```
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE p.name =~ "K.+"
OR m.released > 2000
OR "Neo" IN r.roles
RETURN p,r,m
```
One aspect that might be a little surprising is that you can even use patterns as predicates. Where `MATCH` expands the number and shape of patterns matched, a pattern predicate restricts the current result set. It only allows the paths to pass that satisfy the additional patterns as well (or `NOT`).
```
MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE NOT (p)-[:DIRECTED]->()
RETURN p,m
```
Here we find actors, because they sport an `ACTED_IN` relationship but then skip those that ever `DIRECTED` any movie.
There are also more advanced ways of filtering like collection-predicates which we will look at later on.
## Returning Results
So far we’ve returned only nodes, relationships, or paths directly via their identifiers. But the `RETURN` clause can actually return any number of expressions. But what are actually expressions in Cypher?
The simplest expressions are literal values like numbers, strings and arrays as `[1,2,3]`, and maps like `{name:"Tom Hanks", born:1964, movies:["Forrest Gump", …​], count:13}`. You can access individual properties of any node, relationship, or map with a dot-syntax like `n.name`. Individual elements or slices of arrays can be retrieved with subscripts like `names[0]` or `movies[1..-1]`. Each function evaluation like `length(array)`, `toInt("12")`, `substring("2014-07-01",0,4)`, or `coalesce(p.nickname,"n/a")` is also an expression.
Predicates that you’d use in `WHERE` count as boolean expressions.
Of course simpler expressions can be composed and concatenated to form more complex expressions.
By default the expression itself will be used as label for the column, in many cases you want to alias that with a more understandable name using `expression AS alias`. You can later on refer to that column using its alias.
```
MATCH (p:Person)
RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, {name: p.name, label:head(labels(p))} AS person
```
If you’re interested in unique results you can use the `DISTINCT` keyword after `RETURN` to indicate that.
## Aggregating Information
In many cases you want to aggregate or group the data that you encounter while traversing patterns in your graph. In Cypher aggregation happens in the `RETURN` clause while computing your final results. Many common aggregation functions are supported, e.g. `count`, `sum`, `avg`, `min`, and `max`, but there are several more.
Counting the number of people in your database could be achieved by this:
```
MATCH (:Person)
RETURN count(*) as people
```
Please note that `NULL` values are skipped during aggregation. For aggregating only unique values use `DISTINCT`, like in `count(DISTINCT role)`.
Aggregation in Cypher just works. You specify which result columns you want to aggregate and *Cypher will use all non-aggregated columns as grouping keys*.
Aggregation affects which data is still visible in ordering or later query parts.
To find out how often an actor and director worked together, you’d run this statement:
```
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
RETURN actor,director,count(*) as collaborations
```
Frequently you want to sort and paginate after aggregating a `count(x)`.
## Ordering and Pagination
Ordering works like in other query languages, with an `ORDER BY expression [ASC|DESC]` clause. The expression can be any expression discussed before as long as it is computable from the returned information.
So for instance if you return `person.name` you can still `ORDER BY person.age` as both are accessible from the `person` reference. You cannot order by things that you can’t infer from the information you return. This is especially important with aggregation and `DISTINCT` return values as both remove the visibility of data that is aggregated.
Pagination is a straightforward use of `SKIP {offset} LIMIT {count}`.
A common pattern is to aggregate for a count (score or frequency), order by it and only return the top-n entries.
For instance to find the most prolific actors you could do:
```
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN a,count(*) as appearances
ORDER BY appearances DESC
LIMIT 10;
```
## Collecting Aggregation
The most helpful aggregation function is `collect`, which, as the name says, collects all aggregated values into a *real* array or list. This comes very handy in many situations as you don’t loose the detail information while aggregating.
Collect is well suited for retrieving the typical parent-child structures, where one core entity (parent, root or head) is returned per row with all it’s dependent information in associated collections created with `collect`. This means there’s no need to repeat the parent information per each child-row or even running 1+n statements to retrieve the parent and its children individually.
To retrieve the cast of each movie in our database you could use this statement:
```
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title as movie, collect(a.name) as cast, count(*) as actors
```
The lists created by collect can either be used from the client consuming the Cypher results or directly within a statement with any of the collection functions or predicates. |
| Shard | 37 (laksa) |
| Root Hash | 12828843287614304637 |
| Unparsed URL | com,neo4j!/graphgists/getting-the-results-you-want/ s443 |