15.4. Using

The USING clause is used to influence the decisions of the planner when building an execution plan for a query.

[Caution]Caution

Forcing planner behavior is an advanced feature, and should be used with caution by experienced developers and/or database administrators only, as it may cause queries to perform poorly.

Introduction

When executing a query, Neo4j needs to decide where in the query graph to start matching. This is done by looking at the MATCH clause and the WHERE conditions and using that information to find useful indexes, or other starting points.

However, the selected index might not always be the best choice. Sometimes multiple indexes are possible candidates, and the query planner picks the wrong one from a performance point of view. And in some circumstances (albeit rarely) it is better not to use an index at all.

You can force Neo4j to use a specific starting point through the USING clause. This is called giving a planner hint. There are three types of planner hints: index hints, scan hints, and join hints.

[Note]Note

You cannot use planner hints if your query has a START clause.

The following graph is used for the examples below:

Figure 15.1. Graph

Query 

MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' })
RETURN 1 AS column

The following query will be used in some of the examples on this page. It has intentionally been constructed in such a way that the statistical information will be inaccurate for the particular subgraph that this query matches. For this reason, it can be improved by supplying planner hints.

Query plan 

+------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| Operator         | Estimated Rows | Rows | DB Hits | Variables                                                         | Other                                               |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +ProduceResults  |              0 |    1 |       0 | column                                                            | column                                              |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Projection      |              0 |    1 |       0 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | {  AUTOINT3}                                        |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Filter          |              0 |    1 |       2 | anon[122], anon[41], anon[68], conway, cs, liskov, wing           | liskov:Scientist AND liskov.name == {  AUTOSTRING0} |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Expand(All)     |              0 |    1 |       3 | anon[41], liskov -- anon[122], anon[68], conway, cs, wing         | (wing)<-[:KNOWS]-(liskov)                           |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Filter          |              1 |    2 |       2 | anon[122], anon[68], conway, cs, wing                             | NOT(anon[122] == anon[68]) AND wing:Scientist       |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Expand(All)     |              1 |    3 |       4 | anon[68], wing -- anon[122], conway, cs                           | (cs)<-[:RESEARCHED]-(wing)                          |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Filter          |              0 |    1 |       4 | anon[122], conway, cs                                             | conway.name == {  AUTOSTRING2} AND conway:Scientist |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Expand(All)     |              3 |    3 |       4 | anon[122], conway -- cs                                           | (cs)<-[:RESEARCHED]-(conway)                        |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +Filter          |              1 |    1 |       3 | cs                                                                | cs.name == {  AUTOSTRING1}                          |
| |                +----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+
| +NodeByLabelScan |              3 |    3 |       4 | cs                                                                | :Science                                            |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-----------------------------------------------------+

Total database accesses: 26

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) RETURN 1 AS column

Index hints

Index hints are used to specify which index, if any, the planner should use as a starting point. This can be beneficial in cases where the index statistics are not accurate for the specific values that the query at hand is known to use, which would result in the planner picking a non-optimal index. To supply an index hint, use USING INDEX variable:Label(property) after the applicable MATCH clause.

It is possible to supply several index hints, but keep in mind that several starting points will require the use of a potentially expensive join later in the query plan.

Query using an index hint

The query above will not naturally pick an index to solve the plan. This is because the graph is very small, and label scans are faster for small databases. In general, however, query performance is ranked by the dbhit metric, and we see that using an index is slightly better for this query.

Query 

MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' })
USING INDEX liskov:Scientist(name)
RETURN liskov.born AS column

Returns the year Barbara Liskov was born.

Query plan 

+-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| Operator        | Estimated Rows | Rows | DB Hits | Variables                                                         | Other                                                                              |
+-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +ProduceResults |              0 |    1 |       0 | column                                                            | column                                                                             |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Projection     |              0 |    1 |       1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | liskov.born                                                                        |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Filter         |              0 |    1 |       4 | anon[122], anon[41], anon[68], conway, cs, liskov, wing           | conway.name == {  AUTOSTRING2} AND NOT(anon[122] == anon[68]) AND conway:Scientist |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Expand(All)    |              0 |    3 |       4 | anon[122], conway -- anon[41], anon[68], cs, liskov, wing         | (cs)<-[:RESEARCHED]-(conway)                                                       |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Filter         |              0 |    1 |       4 | anon[41], anon[68], cs, liskov, wing                              | cs:Science AND cs.name == {  AUTOSTRING1}                                          |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Expand(All)    |              0 |    2 |       3 | anon[68], cs -- anon[41], liskov, wing                            | (wing)-[:RESEARCHED]->(cs)                                                         |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Filter         |              0 |    1 |       1 | anon[41], liskov, wing                                            | wing:Scientist                                                                     |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +Expand(All)    |              0 |    1 |       2 | anon[41], wing -- liskov                                          | (liskov)-[:KNOWS]->(wing)                                                          |
| |               +----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+
| +NodeIndexSeek  |              1 |    1 |       2 | liskov                                                            | :Scientist(name)                                                                   |
+-----------------+----------------+------+---------+-------------------------------------------------------------------+------------------------------------------------------------------------------------+

Total database accesses: 21

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) RETURN liskov.born AS column

Query using multiple index hints

Supplying one index hint changed the starting point of the query, but the plan is still linear, meaning it only has one starting point. If we give the planner yet another index hint, we force it to use two starting points, one at each end of the match. It will then join these two branches using a join operator.

Query 

MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' })
USING INDEX liskov:Scientist(name)
USING INDEX conway:Scientist(name)
RETURN liskov.born AS column

Returns the year Barbara Liskov was born, using a slightly better plan.

Query plan 

+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| Operator         | Estimated Rows | Rows | DB Hits | Variables                                                         | Other                                     |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +ProduceResults  |              0 |    1 |       0 | column                                                            | column                                    |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Projection      |              0 |    1 |       1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | liskov.born                               |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Filter          |              0 |    1 |       0 | anon[122], anon[41], anon[68], conway, cs, liskov, wing           | NOT(anon[122] == anon[68])                |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +NodeHashJoin    |              0 |    1 |       0 | anon[41], anon[68], liskov, wing -- anon[122], conway, cs         | cs                                        |
| |\               +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Filter        |              1 |    1 |       1 | anon[122], conway, cs                                             | cs.name == {  AUTOSTRING1}                |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Expand(All)   |              1 |    1 |       2 | anon[122], cs -- conway                                           | (conway)-[:RESEARCHED]->(cs)              |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +NodeIndexSeek |              1 |    1 |       2 | conway                                                            | :Scientist(name)                          |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Filter          |              0 |    1 |       4 | anon[41], anon[68], cs, liskov, wing                              | cs:Science AND cs.name == {  AUTOSTRING1} |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Expand(All)     |              0 |    2 |       3 | anon[68], cs -- anon[41], liskov, wing                            | (wing)-[:RESEARCHED]->(cs)                |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Filter          |              0 |    1 |       1 | anon[41], liskov, wing                                            | wing:Scientist                            |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Expand(All)     |              0 |    1 |       2 | anon[41], wing -- liskov                                          | (liskov)-[:KNOWS]->(wing)                 |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +NodeIndexSeek   |              1 |    1 |       2 | liskov                                                            | :Scientist(name)                          |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+

Total database accesses: 18

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) RETURN liskov.born AS column

Scan hints

If your query matches large parts of an index, it might be faster to scan the label and filter out nodes that do not match. To do this, you can use USING SCAN variable:Label after the applicable MATCH clause. This will force Cypher to not use an index that could have been used, and instead do a label scan.

Hinting a label scan

If the best performance is to be had by scanning all nodes in a label and then filtering on that set, use USING SCAN.

Query 

MATCH (s:Scientist)
USING SCAN s:Scientist
WHERE s.born < 1939
RETURN s.born AS column

Returns all scientists born before 1939.

Query plan 

+------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+
| Operator         | Estimated Rows | Rows | DB Hits | Variables   | Other                                                             |
+------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+
| +ProduceResults  |              0 |    2 |       0 | column      | column                                                            |
| |                +----------------+------+---------+-------------+-------------------------------------------------------------------+
| +Projection      |              0 |    2 |       2 | column -- s | s.born                                                            |
| |                +----------------+------+---------+-------------+-------------------------------------------------------------------+
| +Filter          |              0 |    2 |       7 | s           | AndedPropertyComparablePredicates(s,s.born,s.born < {  AUTOINT0}) |
| |                +----------------+------+---------+-------------+-------------------------------------------------------------------+
| +NodeByLabelScan |              7 |    7 |       8 | s           | :Scientist                                                        |
+------------------+----------------+------+---------+-------------+-------------------------------------------------------------------+

Total database accesses: 17

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (s:Scientist) USING SCAN s:Scientist WHERE s.born < 1939 RETURN s.born AS column

Join hints

Join hints are the most advanced type of hints, and are not used to find starting points for the query execution plan, but to enforce that joins are made at specified points. This implies that there has to be more than one starting point (leaf) in the plan, in order for the query to be able to join the two branches ascending from these leaves. Due to this nature, joins, and subsequently join hints, will force the planner to look for additional starting points, and in the case where there are no more good ones, potentially pick a very bad starting point. This will negatively affect query performance. In other cases, the hint might force the planner to pick a seemingly bad starting point, which in reality proves to be a very good one.

Hinting a join on a single node

In the example above using multiple index hints, we saw that the planner chose to do a join on the cs node. This means that the relationship between wing and cs was traversed in the outgoing direction, which is better statistically because the pattern ()-[:RESEARCHED]->(:Science) is more common than the pattern (:Scientist)-[:RESEARCHED]->(). However, in the actual graph, the cs node only has two such relationships, so expanding from it will be beneficial to expanding from the wing node. We can force the join to happen on wing instead with a join hint.

Query 

MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(conway:Scientist { name: 'Conway' })
USING INDEX liskov:Scientist(name)
USING INDEX conway:Scientist(name)
USING JOIN ON wing
RETURN wing.born AS column

Returns the birth date of Jeanette Wing, using a slightly better plan.

Query plan 

+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| Operator         | Estimated Rows | Rows | DB Hits | Variables                                                         | Other                                     |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +ProduceResults  |              0 |    1 |       0 | column                                                            | column                                    |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Projection      |              0 |    1 |       1 | column -- anon[122], anon[41], anon[68], conway, cs, liskov, wing | wing.born                                 |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +NodeHashJoin    |              0 |    1 |       0 | anon[41], liskov -- anon[122], anon[68], conway, cs, wing         | wing                                      |
| |\               +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Filter        |              1 |    2 |       0 | anon[122], anon[68], conway, cs, wing                             | NOT(anon[122] == anon[68])                |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Expand(All)   |              1 |    3 |       4 | anon[68], wing -- anon[122], conway, cs                           | (cs)<-[:RESEARCHED]-(wing)                |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Filter        |              0 |    1 |       2 | anon[122], conway, cs                                             | cs:Science AND cs.name == {  AUTOSTRING1} |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +Expand(All)   |              1 |    1 |       2 | anon[122], cs -- conway                                           | (conway)-[:RESEARCHED]->(cs)              |
| | |              +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| | +NodeIndexSeek |              1 |    1 |       2 | conway                                                            | :Scientist(name)                          |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Filter          |              0 |    1 |       1 | anon[41], liskov, wing                                            | wing:Scientist                            |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +Expand(All)     |              0 |    1 |       2 | anon[41], wing -- liskov                                          | (liskov)-[:KNOWS]->(wing)                 |
| |                +----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+
| +NodeIndexSeek   |              1 |    1 |       2 | liskov                                                            | :Scientist(name)                          |
+------------------+----------------+------+---------+-------------------------------------------------------------------+-------------------------------------------+

Total database accesses: 16

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist)-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway'}) USING INDEX liskov:Scientist(name) USING INDEX conway:Scientist(name) USING JOIN ON wing RETURN wing.born AS column

Hinting a join on multiple nodes

The query planner can be made to produce a join between several specific points. This requires the query to expand from the same node from several directions.

Query 

MATCH (liskov:Scientist { name:'Liskov' })-[:KNOWS]->(wing:Scientist { name:'Wing' })-[:RESEARCHED]->(cs:Science { name:'Computer Science' })<-[:RESEARCHED]-(liskov)
USING INDEX liskov:Scientist(name)
USING JOIN ON liskov, cs
RETURN wing.born AS column

Returns the birth date of Jeanette Wing.

Query plan 

+------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| Operator         | Estimated Rows | Rows | DB Hits | Variables                                                 | Other                                           |
+------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +ProduceResults  |              0 |    1 |       0 | column                                                    | column                                          |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Projection      |              0 |    1 |       1 | column -- anon[136], anon[41], anon[82], cs, liskov, wing | wing.born                                       |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Filter          |              0 |    1 |       0 | anon[136], anon[41], anon[82], cs, liskov, wing           | NOT(anon[136] == anon[82])                      |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +NodeHashJoin    |              0 |    1 |       0 | anon[41], anon[82], wing -- anon[136], cs, liskov         | liskov, cs                                      |
| |\               +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| | +Filter        |              1 |    1 |       2 | anon[136], cs, liskov                                     | cs.name == {  AUTOSTRING2} AND cs:Science       |
| | |              +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| | +Expand(All)   |              1 |    1 |       2 | anon[136], cs -- liskov                                   | (liskov)-[:RESEARCHED]->(cs)                    |
| | |              +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| | +NodeIndexSeek |              1 |    1 |       2 | liskov                                                    | :Scientist(name)                                |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Filter          |              0 |    1 |       4 | anon[41], anon[82], cs, liskov, wing                      | cs:Science AND cs.name == {  AUTOSTRING2}       |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Expand(All)     |              0 |    2 |       3 | anon[82], cs -- anon[41], liskov, wing                    | (wing)-[:RESEARCHED]->(cs)                      |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Filter          |              0 |    1 |       2 | anon[41], liskov, wing                                    | wing:Scientist AND wing.name == {  AUTOSTRING1} |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +Expand(All)     |              0 |    1 |       2 | anon[41], wing -- liskov                                  | (liskov)-[:KNOWS]->(wing)                       |
| |                +----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+
| +NodeIndexSeek   |              1 |    1 |       2 | liskov                                                    | :Scientist(name)                                |
+------------------+----------------+------+---------+-----------------------------------------------------------+-------------------------------------------------+

Total database accesses: 20

Try this query live  CREATE INDEX ON :Scientist(name) CREATE INDEX ON :Science(name) CREATE (liskov:Scientist {name:'Liskov', born: 1939})-[:KNOWS]->(wing:Scientist {name:'Wing', born: 1956})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(conway:Scientist {name: 'Conway', born: 1938}), (liskov)-[:RESEARCHED]->(cs), (wing)-[:RESEARCHED]->(:Science {name: 'Engineering'}), (chemistry:Science {name: 'Chemistry'})<-[:RESEARCHED]-(:Scientist {name: 'Curie', born: 1867}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Arden'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Franklin'}), (chemistry)<-[:RESEARCHED]-(:Scientist {name: 'Harrison'}) MATCH (liskov:Scientist {name:'Liskov'})-[:KNOWS]->(wing:Scientist {name:'Wing'})-[:RESEARCHED]->(cs:Science {name:'Computer Science'})<-[:RESEARCHED]-(liskov) USING INDEX liskov:Scientist(name) USING JOIN ON liskov, cs RETURN wing.born AS column