Given is the following graph for Neo4j 2.1.7:
CREATE
(:Application {Name: "Test Application", Aliases: ["Test", "App", "TestProject"]}),
(:Application {Name: "Another Application", Aliases: ["A-App", "XYZ", "XYProject"]}),
(:Application {Name: "Database X", Aliases: ["DB-App", "DB", "DB-Project"]}),
(:System {Name: "Server1", Application: "TestProject"}),
(:System {Name: "Server2", Application: "Test Application"}),
(:System {Name: "Server3", Application: "another App"}),
(:System {Name: "Server4", Application: "Some Database"}),
(:System {Name: "Server5", Application: "App"}),
(:System {Name: "Server6", Application: "App XY"}),
(:System {Name: "Server7", Application: "App DB"}),
(:System {Name: "Server8", Application: "Test"}),
(:System {Name: "Server9", Application: "TestProject"}),
(:System {Name: "Server10", Application: "test"}),
(:System {Name: "Server11", Application: "App XY"});
CREATE INDEX ON :Application(Name);
CREATE INDEX ON :Application(Aliases);
CREATE INDEX ON :System(Application);
Following queries are using the schema index:
PROFILE
MATCH (a:Application { Name: "Test Application" })
MATCH (s:System)
WHERE s.Application = a.Name
RETURN a,s;
neo4j-sh (?)$ PROFILE MATCH (a:Application { Name: "Test Application" }) MATCH (s:System) WHERE s.Application = a.Name RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a | s |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 1 row
==>
==> SchemaIndex(0)
==> |
==> +SchemaIndex(1)
==>
==> +----------------+------+--------+-------------+-------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +----------------+------+--------+-------------+-------------------------------------------+
==> | SchemaIndex(0) | 1 | 4 | s, s | Property(a,Name(0)); :System(Application) |
==> | SchemaIndex(1) | 1 | 2 | a, a | { AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+-------------------------------------------+
==>
==> Total database accesses: 6
--
PROFILE
MATCH (a:Application { Name: "Test Application" })
MATCH (s:System)
WHERE s.Application IN a.Aliases
RETURN a,s;
neo4j-sh (?)$ PROFILE MATCH (a:Application { Name: "Test Application" }) MATCH (s:System) WHERE s.Application IN a.Aliases RETURN a,s;
==> +----------------------------------------------------------------------------------------------------------------------------+
==> | a | s |
==> +----------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"} |
==> +----------------------------------------------------------------------------------------------------------------------------+
==> 4 rows
==>
==> SchemaIndex(0)
==> |
==> +SchemaIndex(1)
==>
==> +----------------+------+--------+-------------+----------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +----------------+------+--------+-------------+----------------------------------------------+
==> | SchemaIndex(0) | 4 | 9 | s, s | Property(a,Aliases(1)); :System(Application) |
==> | SchemaIndex(1) | 1 | 2 | a, a | { AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+----------------------------------------------+
==>
==> Total database accesses: 11
While combined with OR operator are not:
PROFILE
MATCH (a:Application { Name: "Test Application"})
MATCH (s:System)
WHERE s.Application = a.Name OR s.Application IN a.Aliases
RETURN a,s;
neo4j-sh (?)$ PROFILE MATCH (a:Application { Name: "Test Application"}) MATCH (s:System) WHERE s.Application = a.Name OR s.Application IN a.Aliases RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a | s |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"} |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 5 rows
==>
==> Filter
==> |
==> +NodeByLabel
==> |
==> +SchemaIndex
==>
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==> | Filter | 5 | 126 | | (Property(s,Application(2)) == Property(a,Name(0)) OR any(-_-INNER-_- in Property(a,Aliases(1)) where Property(s,Application(2)) == -_-INNER-_-)) |
==> | NodeByLabel | 11 | 12 | s, s | :System |
==> | SchemaIndex | 1 | 2 | a, a | { AUTOSTRING0}; :Application(Name) |
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==>
==> Total database accesses: 140
But this one works??
PROFILE
MATCH (a:Application { Name: "Test Application"})
MATCH (s:System)
WHERE s.Application IN (a.Aliases + a.Name)
RETURN a,s;
neo4j-sh (?)$ PROFILE MATCH (a:Application { Name: "Test Application"}) MATCH (s:System) WHERE s.Application IN (a.Aliases + a.Name) RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a | s |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 5 rows
==>
==> SchemaIndex(0)
==> |
==> +SchemaIndex(1)
==>
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==> | SchemaIndex(0) | 5 | 13 | s, s | Add(Property(a,Aliases(1)),Property(a,Name(0))); :System(Application) |
==> | SchemaIndex(1) | 1 | 2 | a, a | { AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==>
==> Total database accesses: 15
Why is the query with OR operator not using the new indexes?
Because the rewriter is not smart enough to recognize this corner case.
You already answered your own question, with which I would have also suggested.