### 3.7.3. Combining operators

The combining operators are used to piece together other operators.

Operators:

The following graph is used for the examples below:

#### 3.7.3.1. Apply

`Apply` works by performing a nested loop. Every row being produced on the left-hand side of the `Apply` operator will be fed to the leaf operator on the right-hand side, and then `Apply` will yield the combined results. `Apply`, being a nested loop, can be seen as a warning that a better plan was not found.

Query.

``````MATCH (p:Person)-[:FRIENDS_WITH]->(f)
WITH p, count(f) AS fs
WHERE fs > 2
OPTIONAL MATCH (p)-[:WORKS_IN]->(city)
RETURN city.name``````

Finds all the people with more than two friends and returns the city they work in.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime INTERPRETED

+----------------------+----------------+----------------------------------------------+----------------------------------------+
| Operator             | Estimated Rows | Variables                                    | Other                                  |
+----------------------+----------------+----------------------------------------------+----------------------------------------+
| +ProduceResults      |              1 | anon[70], anon[93], city, city.name, fs, p   |                                        |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +Projection          |              1 | city.name -- anon[70], anon[93], city, fs, p | {city.name : city.name}                |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +OptionalExpand(All) |              1 | anon[93], city -- anon[70], fs, p            | (p)-[:WORKS_IN]->(city)                |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +Filter              |              1 | anon[70], fs, p                              | anon[70]                               |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +Projection          |              1 | anon[70] -- fs, p                            | {p : p, fs : fs,  : fs > {  AUTOINT0}} |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +EagerAggregation    |              1 | fs -- p                                      | p                                      |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +Expand(All)         |              2 | anon[17], f -- p                             | (p)-[:FRIENDS_WITH]->(f)               |
| |                    +----------------+----------------------------------------------+----------------------------------------+
| +NodeByLabelScan     |             14 | p                                            | :Person                                |
+----------------------+----------------+----------------------------------------------+----------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (p:Person)-[:FRIENDS_WITH]->(f) WITH p, count(f) as fs WHERE fs > 2 OPTIONAL MATCH (p)-[:WORKS_IN]->(city) RETURN city.name

#### 3.7.3.2. SemiApply

Tests for the existence of a pattern predicate. `SemiApply` takes a row from its child operator and feeds it to the leaf operator on the right-hand side. If the right-hand side operator tree yields at least one row, the row from the left-hand side is yielded by the `SemiApply` operator. This makes `SemiApply` a filtering operator, used mostly for pattern predicates in queries.

Query.

``````MATCH (p:Person)
WHERE (p)-[:FRIENDS_WITH]->()
RETURN p.name``````

Finds all the people who have friends.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+------------------+----------------+-------------+-------------------------------------------------------+
| Operator         | Estimated Rows | Variables   | Other                                                 |
+------------------+----------------+-------------+-------------------------------------------------------+
| +ProduceResults  |              4 | p, p.name   |                                                       |
| |                +----------------+-------------+-------------------------------------------------------+
| +Projection      |              4 | p.name -- p | {p.name : p.name}                                     |
| |                +----------------+-------------+-------------------------------------------------------+
| +Filter          |              4 | p           | GetDegreePrimitive(0,Some(FRIENDS_WITH),OUTGOING) > 0 |
| |                +----------------+-------------+-------------------------------------------------------+
| +NodeByLabelScan |             14 | p           | :Person                                               |
+------------------+----------------+-------------+-------------------------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (p:Person) WHERE (p)-[:FRIENDS_WITH]->() RETURN p.name

#### 3.7.3.3. AntiSemiApply

Tests for the absence of a pattern. `AntiSemiApply` takes a row from its child operator and feeds it to the leaf operator on the right-hand side. If the right-hand side operator tree yields at least one row, the row from the left-hand side is yielded by the `AntiSemiApply` operator. This makes `AntiSemiApply` a filtering operator, used for pattern predicates in queries.

Query.

``````MATCH (me:Person { name: "me" }),(other:Person)
WHERE NOT (me)-[:FRIENDS_WITH]->(other)
RETURN other.name``````

Finds the names of all the people who are not my friends.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+--------------------+----------------+-------------------------+-------------------------------+
| Operator           | Estimated Rows | Variables               | Other                         |
+--------------------+----------------+-------------------------+-------------------------------+
| +ProduceResults    |              4 | me, other, other.name   |                               |
| |                  +----------------+-------------------------+-------------------------------+
| +Projection        |              4 | other.name -- me, other | {other.name : other.name}     |
| |                  +----------------+-------------------------+-------------------------------+
| +AntiSemiApply     |              4 | me, other               |                               |
| |\                 +----------------+-------------------------+-------------------------------+
| | +Expand(Into)    |              0 | anon[63] -- me, other   | (me)-[:FRIENDS_WITH]->(other) |
| | |                +----------------+-------------------------+-------------------------------+
| | +Argument        |             14 | me, other               |                               |
| |                  +----------------+-------------------------+-------------------------------+
| +CartesianProduct  |             14 | me -- other             |                               |
| |\                 +----------------+-------------------------+-------------------------------+
| | +NodeByLabelScan |             14 | other                   | :Person                       |
| |                  +----------------+-------------------------+-------------------------------+
| +NodeIndexSeek     |              1 | me                      | :Person(name)                 |
+--------------------+----------------+-------------------------+-------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (me:Person {name: "me"}), (other:Person) WHERE NOT (me)-[:FRIENDS_WITH]->(other) RETURN other.name

#### 3.7.3.4. LetSemiApply

Tests for the existence of a pattern predicate. When a query contains multiple pattern predicates `LetSemiApply` will be used to evaluate the first of these. It will record the result of evaluating the predicate but will leave any filtering to another operator.

Query.

``````MATCH (other:Person)
WHERE (other)-[:FRIENDS_WITH]->() OR (other)-[:WORKS_IN]->()
RETURN other.name``````

Finds the names of all the people who have a friend or who work somewhere. The `LetSemiApply` operator will be used to check for the existence of the `FRIENDS_WITH` relationship from each person.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+------------------+----------------+---------------------+--------------------------------------------------------------------------------------------------------------+
| Operator         | Estimated Rows | Variables           | Other                                                                                                        |
+------------------+----------------+---------------------+--------------------------------------------------------------------------------------------------------------+
| +ProduceResults  |              7 | other, other.name   |                                                                                                              |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------------------------------+
| +Projection      |              7 | other.name -- other | {other.name : other.name}                                                                                    |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------------------------------+
| +Filter          |              7 | other               | OR( GetDegreePrimitive(0,Some(FRIENDS_WITH),OUTGOING) > 0, GetDegreePrimitive(0,Some(WORKS_IN),OUTGOING) > 0 |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan |             14 | other               | :Person                                                                                                      |
+------------------+----------------+---------------------+--------------------------------------------------------------------------------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (other:Person) WHERE (other)-[:FRIENDS_WITH]->() OR (other)-[:WORKS_IN]->() RETURN other.name

#### 3.7.3.5. LetAntiSemiApply

Tests for the absence of a pattern. When a query contains multiple pattern predicates `LetAntiSemiApply` will be used to evaluate the first of these. It will record the result of evaluating the predicate but will leave any filtering to another operator. The following query will find all the people who don’t have any friends or who work somewhere.

Query.

``````MATCH (other:Person)
WHERE NOT ((other)-[:FRIENDS_WITH]->()) OR (other)-[:WORKS_IN]->()
RETURN other.name``````

Finds all the people who don’t have any friends or who work somewhere. The `LetAntiSemiApply` operator will be used to check for the absence of the `FRIENDS_WITH` relationship from each person.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+------------------+----------------+---------------------+---------------------------------------------------------------------------------------------------------------+
| Operator         | Estimated Rows | Variables           | Other                                                                                                         |
+------------------+----------------+---------------------+---------------------------------------------------------------------------------------------------------------+
| +ProduceResults  |              7 | other, other.name   |                                                                                                               |
| |                +----------------+---------------------+---------------------------------------------------------------------------------------------------------------+
| +Projection      |              7 | other.name -- other | {other.name : other.name}                                                                                     |
| |                +----------------+---------------------+---------------------------------------------------------------------------------------------------------------+
| +Filter          |              7 | other               | OR( GetDegreePrimitive(0,Some(FRIENDS_WITH),OUTGOING) <= 0, GetDegreePrimitive(0,Some(WORKS_IN),OUTGOING) > 0 |
| |                +----------------+---------------------+---------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan |             14 | other               | :Person                                                                                                       |
+------------------+----------------+---------------------+---------------------------------------------------------------------------------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (other:Person) WHERE NOT((other)-[:FRIENDS_WITH]->()) OR (other)-[:WORKS_IN]->() RETURN other.name

#### 3.7.3.6. SelectOrSemiApply

Tests for the existence of a pattern predicate and evaluates a predicate. This operator allows for the mixing of normal predicates and pattern predicates that check for the existence of a pattern. First the normal expression predicate is evaluated, and only if it returns `false` the costly pattern predicate evaluation is performed.

Query.

``````MATCH (other:Person)
WHERE other.age > 25 OR (other)-[:FRIENDS_WITH]->()
RETURN other.name``````

Finds the names of all people who have friends, or are older than '25'.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+------------------+----------------+---------------------+-------------------------------------------------------------------------------------+
| Operator         | Estimated Rows | Variables           | Other                                                                               |
+------------------+----------------+---------------------+-------------------------------------------------------------------------------------+
| +ProduceResults  |              4 | other, other.name   |                                                                                     |
| |                +----------------+---------------------+-------------------------------------------------------------------------------------+
| +Projection      |              4 | other.name -- other | {other.name : other.name}                                                           |
| |                +----------------+---------------------+-------------------------------------------------------------------------------------+
| +Filter          |              4 | other               | OR( other.age > {  AUTOINT0}, GetDegreePrimitive(0,Some(FRIENDS_WITH),OUTGOING) > 0 |
| |                +----------------+---------------------+-------------------------------------------------------------------------------------+
| +NodeByLabelScan |             14 | other               | :Person                                                                             |
+------------------+----------------+---------------------+-------------------------------------------------------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (other:Person) WHERE other.age > 25 OR (other)-[:FRIENDS_WITH]->() RETURN other.name

#### 3.7.3.7. SelectOrAntiSemiApply

Tests for the absence of a pattern predicate and evaluates a predicate.

Query.

``````MATCH (other:Person)
WHERE other.age > 25 OR NOT (other)-[:FRIENDS_WITH]->()
RETURN other.name``````

Finds the names of all people who do not have friends, or are older than '25'.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime SLOTTED

+------------------+----------------+---------------------+--------------------------------------------------------------------------------------+
| Operator         | Estimated Rows | Variables           | Other                                                                                |
+------------------+----------------+---------------------+--------------------------------------------------------------------------------------+
| +ProduceResults  |              4 | other, other.name   |                                                                                      |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------+
| +Projection      |              4 | other.name -- other | {other.name : other.name}                                                            |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------+
| +Filter          |              4 | other               | OR( other.age > {  AUTOINT0}, GetDegreePrimitive(0,Some(FRIENDS_WITH),OUTGOING) <= 0 |
| |                +----------------+---------------------+--------------------------------------------------------------------------------------+
| +NodeByLabelScan |             14 | other               | :Person                                                                              |
+------------------+----------------+---------------------+--------------------------------------------------------------------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (other:Person) WHERE other.age > 25 OR NOT (other)-[:FRIENDS_WITH]->() RETURN other.name

#### 3.7.3.8. ConditionalApply

Checks whether a variable is not `null`, and if so the right-hand side will be executed.

Query.

``````MERGE (p:Person { name: 'Andres' })
ON MATCH SET p.exists = TRUE``````

Looks for the existence of a person called 'Andres', and if found sets the `exists` property to `true`.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime INTERPRETED

+-----------------------+----------------+-----------+---------------+
| Operator              | Estimated Rows | Variables | Other         |
+-----------------------+----------------+-----------+---------------+
| +ProduceResults       |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +EmptyResult          |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +AntiConditionalApply |              1 | p         |               |
| |\                    +----------------+-----------+---------------+
| | +MergeCreateNode    |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +ConditionalApply     |              1 | p         |               |
| |\                    +----------------+-----------+---------------+
| | +SetProperty        |              1 | p         |               |
| | |                   +----------------+-----------+---------------+
| | +Argument           |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +Optional             |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +NodeIndexSeek        |              1 | p         | :Person(name) |
+-----------------------+----------------+-----------+---------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MERGE (p:Person {name: 'Andres'}) ON MATCH SET p.exists = true

#### 3.7.3.9. AntiConditionalApply

Checks whether a variable is `null`, and if so the right-hand side will be executed.

Query.

``````MERGE (p:Person { name: 'Andres' })
ON CREATE SET p.exists = TRUE``````

Looks for the existence of a person called 'Andres', and if not found, creates one and sets the `exists` property to `true`.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime INTERPRETED

+-----------------------+----------------+-----------+---------------+
| Operator              | Estimated Rows | Variables | Other         |
+-----------------------+----------------+-----------+---------------+
| +ProduceResults       |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +EmptyResult          |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +AntiConditionalApply |              1 | p         |               |
| |\                    +----------------+-----------+---------------+
| | +SetProperty        |              1 | p         |               |
| | |                   +----------------+-----------+---------------+
| | +MergeCreateNode    |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +Optional             |              1 | p         |               |
| |                     +----------------+-----------+---------------+
| +NodeIndexSeek        |              1 | p         | :Person(name) |
+-----------------------+----------------+-----------+---------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MERGE (p:Person {name: 'Andres'}) ON CREATE SET p.exists = true

#### 3.7.3.10. AssertSameNode

This operator is used to ensure that no uniqueness constraints are violated.

Query.

``MERGE (t:Team { name: 'Engineering', id: 42 })``

Looks for the existence of a team with the supplied name and id, and if one does not exist, it will be created. Owing to the existence of two uniqueness constraints on `:Team(name)` and `:Team(id)`, any node that would be found by the `UniqueIndexSeek` must be the very same node, or the constraints would be violated.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime INTERPRETED

+---------------------------------+----------------+-----------+-------------+
| Operator                        | Estimated Rows | Variables | Other       |
+---------------------------------+----------------+-----------+-------------+
| +ProduceResults                 |              1 | t         |             |
| |                               +----------------+-----------+-------------+
| +EmptyResult                    |              1 | t         |             |
| |                               +----------------+-----------+-------------+
| +AntiConditionalApply           |              1 | t         |             |
| |\                              +----------------+-----------+-------------+
| | +MergeCreateNode              |              1 | t         |             |
| |                               +----------------+-----------+-------------+
| +Optional                       |              1 | t         |             |
| |                               +----------------+-----------+-------------+
| +AssertSameNode                 |              0 | t         |             |
| |\                              +----------------+-----------+-------------+
| | +NodeUniqueIndexSeek(Locking) |              1 | t         | :Team(name) |
| |                               +----------------+-----------+-------------+
| +NodeUniqueIndexSeek(Locking)   |              1 | t         | :Team(id)   |
+---------------------------------+----------------+-----------+-------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MERGE (t:Team {name: 'Engineering', id: 42})

#### 3.7.3.11. NodeHashJoin

Using a hash table, a `NodeHashJoin` joins the input coming from the left with the input coming from the right.

Query.

``````MATCH (andy:Person { name:'Andreas' })-[:WORKS_IN]->(loc)<-[:WORKS_IN]-(matt:Person { name:'Mattis' })
RETURN loc.name``````

Returns the name of the location where the matched persons both work.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime COMPILED

+------------------+----------------+-------------------------------------------------+---------------------------+
| Operator         | Estimated Rows | Variables                                       | Other                     |
+------------------+----------------+-------------------------------------------------+---------------------------+
| +ProduceResults  |             10 | anon[39], anon[58], andy, loc, loc.name, matt   |                           |
| |                +----------------+-------------------------------------------------+---------------------------+
| +Projection      |             10 | loc.name -- anon[39], anon[58], andy, loc, matt | {loc.name : loc.name}     |
| |                +----------------+-------------------------------------------------+---------------------------+
| +Filter          |             10 | anon[39], anon[58], andy, loc, matt             | NOT(anon[39] = anon[58])  |
| |                +----------------+-------------------------------------------------+---------------------------+
| +NodeHashJoin    |             10 | anon[39], andy -- anon[58], loc, matt           | loc                       |
| |\               +----------------+-------------------------------------------------+---------------------------+
| | +Expand(All)   |             19 | anon[58], loc -- matt                           | (matt)-[:WORKS_IN]->(loc) |
| | |              +----------------+-------------------------------------------------+---------------------------+
| | +NodeIndexSeek |              1 | matt                                            | :Person(name)             |
| |                +----------------+-------------------------------------------------+---------------------------+
| +Expand(All)     |             19 | anon[39], loc -- andy                           | (andy)-[:WORKS_IN]->(loc) |
| |                +----------------+-------------------------------------------------+---------------------------+
| +NodeIndexSeek   |              1 | andy                                            | :Person(name)             |
+------------------+----------------+-------------------------------------------------+---------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (london:Location {name: 'London'}), (person:Person {name: 'Pontus'}) FOREACH(x in range(0,250) | CREATE (person)-[:WORKS_IN]->(london) ) MATCH (andy:Person {name:'Andreas'})-[:WORKS_IN]->(loc)<-[:WORKS_IN]-(matt:Person {name:'Mattis'}) RETURN loc.name

Triadic is used to solve triangular queries, such as the very common 'find my friend-of-friends that are not already my friend'. It does so by putting all the friends in a set, and use that set to check if the friend-of-friends are already connected to me.

Query.

``````MATCH (me:Person)-[:FRIENDS_WITH]-()-[:FRIENDS_WITH]-(other)
WHERE NOT (me)-[:FRIENDS_WITH]-(other)
RETURN other.name``````

Finds the names of all friends of my friends that are not already my friends.

Query plan.

``````Compiler CYPHER 3.3

Planner COST

Runtime INTERPRETED

+-------------------+----------------+-------------------------------------------------------+----------------------------+
| Operator          | Estimated Rows | Variables                                             | Other                      |
+-------------------+----------------+-------------------------------------------------------+----------------------------+
| +ProduceResults   |              0 | anon[18], anon[35], anon[37], me, other, other.name   |                            |
| |                 +----------------+-------------------------------------------------------+----------------------------+
| +Projection       |              0 | other.name -- anon[18], anon[35], anon[37], me, other | {other.name : other.name}  |
| |                 +----------------+-------------------------------------------------------+----------------------------+
| +TriadicSelection |              0 | anon[18], anon[35], anon[37], me, other               | me, anon[35], other        |
| |\                +----------------+-------------------------------------------------------+----------------------------+
| | +Filter         |              0 | anon[18], anon[35], anon[37], me, other               | NOT(anon[18] = anon[37])   |
| | |               +----------------+-------------------------------------------------------+----------------------------+
| | +Expand(All)    |              0 | anon[37], other -- anon[18], anon[35], me             | ()-[:FRIENDS_WITH]-(other) |
| | |               +----------------+-------------------------------------------------------+----------------------------+
| | +Argument       |              4 | anon[18], anon[35], me                                |                            |
| |                 +----------------+-------------------------------------------------------+----------------------------+
| +Expand(All)      |              4 | anon[18], anon[35] -- me                              | (me)-[:FRIENDS_WITH]-()    |
| |                 +----------------+-------------------------------------------------------+----------------------------+
| +NodeByLabelScan  |             14 | me                                                    | :Person                    |
+-------------------+----------------+-------------------------------------------------------+----------------------------+

Total database accesses: ?``````

Try this query live.  CREATE CONSTRAINT ON (team:Team) ASSERT team.name is UNIQUE CREATE CONSTRAINT ON (team:Team) ASSERT team.id is UNIQUE CREATE INDEX ON :Location(name) CREATE INDEX ON :Person(name) CREATE (me:Person {name:'me'}) CREATE (andres:Person {name:'Andres'}) CREATE (andreas:Person {name:'Andreas'}) CREATE (mattias:Person {name:'Mattias'}) CREATE (lovis:Person {name:'Lovis'}) CREATE (pontus:Person {name:'Pontus'}) CREATE (max:Person {name:'Max'}) CREATE (konstantin:Person {name:'Konstantin'}) CREATE (stefan:Person {name:'Stefan'}) CREATE (mats:Person {name:'Mats'}) CREATE (petra:Person {name:'Petra'}) CREATE (craig:Person {name:'Craig'}) CREATE (steven:Person {name:'Steven'}) CREATE (chris:Person {name:'Chris'}) CREATE (london:Location {name:'London'}) CREATE (malmo:Location {name:'Malmo'}) CREATE (sf:Location {name:'San Francisco'}) CREATE (berlin:Location {name:'Berlin'}) CREATE (newyork:Location {name:'New York'}) CREATE (kuala:Location {name:'Kuala Lumpur'}) CREATE (stockholm:Location {name:'Stockholm'}) CREATE (paris:Location {name:'Paris'}) CREATE (madrid:Location {name:'Madrid'}) CREATE (rome:Location {name:'Rome'}) CREATE (england:Country {name:'England'}) CREATE (field:Team {name:'Field'}) CREATE (engineering:Team {name:'Engineering', id: 42}) CREATE (sales:Team {name:'Sales'}) CREATE (monads:Team {name:'Team Monads'}) CREATE (birds:Team {name:'Team Enlightened Birdmen'}) CREATE (quality:Team {name:'Team Quality'}) CREATE (rassilon:Team {name:'Team Rassilon'}) CREATE (executive:Team {name:'Team Executive'}) CREATE (remoting:Team {name:'Team Remoting'}) CREATE (other:Team {name:'Other'}) CREATE (me)-[:WORKS_IN {duration: 190}]->(london) CREATE (andreas)-[:WORKS_IN {duration: 187}]->(london) CREATE (andres)-[:WORKS_IN {duration: 150}]->(london) CREATE (mattias)-[:WORKS_IN {duration: 230}]->(london) CREATE (lovis)-[:WORKS_IN {duration: 230}]->(sf) CREATE (pontus)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (max)-[:WORKS_IN {duration: 230}]->(newyork) CREATE (konstantin)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(london) CREATE (stefan)-[:WORKS_IN {duration: 230}]->(berlin) CREATE (mats)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (petra)-[:WORKS_IN {duration: 230}]->(london) CREATE (craig)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (steven)-[:WORKS_IN {duration: 230}]->(malmo) CREATE (chris)-[:WORKS_IN {duration: 230}]->(madrid) CREATE (london)-[:IN]->(england) CREATE (me)-[:FRIENDS_WITH]->(andres) CREATE (andres)-[:FRIENDS_WITH]->(andreas) MATCH (me:Person)-[:FRIENDS_WITH]-()-[:FRIENDS_WITH]-(other) WHERE NOT (me)-[:FRIENDS_WITH]-(other) RETURN other.name