Relationship property indexes
A relationship index maps the values of one property on one relationship type to the relationships that hold them. It is ordered, so the same index answers equality and range predicates.
CREATE INDEX FOR ()-[r:KNOWS]-() ON (r.since);
CREATE INDEX knows_since IF NOT EXISTS FOR ()-[r:KNOWS]-() ON (r.since); // name and guard are optional
SHOW INDEXES; // label: KNOWS, type: RELATIONSHIP
DROP INDEX FOR ()-[r:KNOWS]-() ON (r.since);
The planner seeks the relationships and matches outwards from each one's endpoint, instead of scanning nodes:
MATCH (a)-[r:KNOWS {since: 2020}]->(b) RETURN a, b;
MATCH (a)-[r:KNOWS]->(b) WHERE r.since >= 2015 AND r.since < 2020 RETURN a, b;
// EXPLAIN → Match: RelationshipIndexSeek(:KNOWS .since)
The seek is used when all of these hold; otherwise the pattern is matched from a node as before, with the same results:
- the relationship names exactly one type and is a single hop;
- it is the first or the last relationship of the pattern;
- the predicate is an inline value or an
AND-ed=,<,<=,>,>=comparison with a literal, a parameter or a value bound by an earlier clause; - neither end node is already bound, and the index finds fewer relationships than the cheaper end node has candidates.
EXPLAIN shows the seek for literal predicates only; with parameters the
choice is made at run time. An index covers one property. It is kept up to date
by every write, including rollback, and like all indexes is stored as a
declaration and rebuilt when the database opens.
A database that declares a relationship index is written in a newer storage format that version 1.0.1 refuses to open. Drop the index and checkpoint before downgrading.
Related articles
Property, range and composite indexes · Constraints and shared uniqueness · EXPLAIN and PROFILE