How Does Pattern Comprehension Interact with the Match Clause?

Hello everyone, I am very new to Cypher. This is probably related to a basic concept but I somehow wasn't able to find the answer to this. Currently, I am looking at pattern comprehension in cypher, but I am very confused about what it does. Here's what the document says:

A pattern comprehension will match the specified pattern just like a normal MATCH clause, with predicates just like a normal WHERE clause, but will yield a custom projection as specified.

However, it seems to have different behaviors based on whether or not a match clause exists. If there is no match clause:

Return [(a:Person)-[]->(b:Movie) | elementId(a) + elementId(b)] as IDs

the statement above returns a single list:

["4:6c7257a5-f51e-4206-bc11-f5aec142409b:84:6c7257a5-f51e-4206-bc11-f5aec142409b:0", "4:6c7257a5-f51e-4206-bc11-f5aec142409b:74:6c7257a5-f51e-4206-bc11-f5aec142409b:0", "4:6c7257a5-f51e-4206-bc11-f5aec142409b:64:6c7257a5-f51e-4206-bc11-f5aec142409b:0", "4:6c7257a5-f51e-4206-bc11-f5aec142409b:54:6c7257a5-f51e-4206-bc11-f5aec142409b:0", "4:6c7257a5-f51e-4206-bc11-f5aec142409b:44:6c7257a5-f51e-4206-bc11-f5aec142409b:0", ...]

However, if there is a match clause:

Match (a:Person)-[]->(b:Movie)
Return [(a)-[]->(b) | elementId(a) + elementId(b)] as IDs

Then this one returns multiple rows, where each row has a small list:

╒══════════════════════════════════════════════════════════════════════╕
│IDs                                                                 │
╞══════════════════════════════════════════════════════════════════════╡
│["4:6c7257a5-f51e-4206-bc11-f5aec142409b:84:6c7257a5-f51e-4206-bc11-f5│
│aec142409b:0"]                                                        │
├──────────────────────────────────────────────────────────────────────┤
│["4:6c7257a5-f51e-4206-bc11-f5aec142409b:74:6c7257a5-f51e-4206-bc11-f5│
│aec142409b:0"]                                                        │
├──────────────────────────────────────────────────────────────────────┤
│["4:6c7257a5-f51e-4206-bc11-f5aec142409b:64:6c7257a5-f51e-4206-bc11-f5│
│aec142409b:0"]                                                        │
├──────────────────────────────────────────────────────────────────────┤
│["4:6c7257a5-f51e-4206-bc11-f5aec142409b:54:6c7257a5-f51e-4206-bc11-f5│
│aec142409b:0"]                                                        │
├──────────────────────────────────────────────────────────────────────┤
│["4:6c7257a5-f51e-4206-bc11-f5aec142409b:44:6c7257a5-f51e-4206-bc11-f5│
│aec142409b:0"]                                                        │
...

Why are these two results different? Am I missing anything about the language? Thanks!

List comprehension is a list operation. That is why you can use it alone in the return statement. List comprehension allows you to optionally filter elements in a list and optionally transform each element, return a list of the results.

Pattern comprehension is a form of list comprehension where the list elements are the rows returned from matching the pattern provided.

In your second scenario, the match is producing multiple rows of data. The return statement will return an information you want from the bounded variables in your match pattern. In your case you are returning a list created with pattern recognition. What happens here is the list is evaluated with each row resulting from the match. The pattern is using variables from the match, so each pattern comprehension is correlated with the results of the match, I.e., it gets reevaluated for each row of values of ‘a’ and ‘b’.

1 Like

To put it simply, a key concept in Cypher:
operations produce rows, and operations execute per row

Your MATCH produced rows of interim results (per distinct path found that matches the pattern). The RETURN expression will be applied upon each of those rows, and so per row a pattern comprehension will execute, and the resulting list will appear per row.

1 Like