Neo4j 2.0.0: Cypher - Index Hints and Neo.ClientError.Schema.NoSuchIndex
One of the features added into the more recent versions of Neo4j’s cypher query language is the ability to tell Cypher which index you’d like to use in your queries.
We’ll use the football dataset, so let’s start by creating an index on the 'name' property of nodes labelled 'Player':
CREATE INDEX ON :Player(name)
Let’s say we want to write a query to find 'Wayne Rooney' while explicitly using this index. We might start with the following query:
MATCH p
USING INDEX p:Player(name)
WHERE p.name = "Wayne Rooney"
RETURN p
If we run that we’ll see this error:
Cannot use index hint in this context. The label and property comparison must be specified on a non-optional node
Label: `Player`
Property name: `name`
Neo.ClientError.Schema.NoSuchIndex
We need to specify the label on the node in the 'MATCH' part of the query for our hint to work e.g.
MATCH (p:Player)
USING INDEX p:Player(name)
WHERE p.name = "Wayne Rooney"
RETURN p
Now we might decide that we want to find 'Wayne Rooney' or 'Robin Van Persie' so we change our query slightly:
MATCH (p:Player)
USING INDEX p:Player(name)
WHERE p.name = "Wayne Rooney" OR p.name = "Robin Van Persie"
RETURN p
But this one fails too!
Cannot use index hint in this context. The label and property comparison must be specified on a non-optional node
Label: `Player`
Property name: `name`
Neo.ClientError.Schema.NoSuchIndex
The problem here is that when you use 'OR' it’s currently not using an index but rather a label scan so the hint to use the index doesn’t make sense to Cypher.
The final way I’ve seen people get confused using index hints is when matching node properties inline e.g.
MATCH (p:Player {name: "Wayne Rooney"})
USING INDEX p:Player(name)
RETURN p
If we run that we’ll be back in the land of exceptions:
Cannot use index hint in this context. The label and property comparison must be specified on a non-optional node
Label: `Player`
Property name: `name`
Neo.ClientError.Schema.NoSuchIndex
We can work around that by pulling out the inline matching of the 'name' property":
MATCH (p:Player)
USING INDEX p:Player(name)
WHERE p.name = "Wayne Rooney"
RETURN p
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.