Indexes and constraints
|
This section documents the current Neo4j This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, as Neo4j iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
Cypher creates and drops schema objects with the same imperative statements used elsewhere — CREATE INDEX,
CREATE CONSTRAINT, SHOW INDEXES, DROP CONSTRAINT — but a Neo4j index only ever accelerates a lookup;
it never enforces anything. Only a constraint rejects a write, and two of the four constraint kinds
(uniqueness and node key) happen to also create a backing index as a side effect.
Index types
Six index kinds cover different value shapes and query predicates.
Range indexes
The default kind, and what plain CREATE INDEX creates: a B-tree-like structure over one or more
properties of a node label or relationship type, usable for equality, range comparisons
(<, ⇐, >, >=, BETWEEN), and STARTS WITH.
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/range-indexes/
CREATE INDEX person_born_range IF NOT EXISTS
FOR (p:Person) ON (p.born);
CREATE INDEX acted_in_roles_range IF NOT EXISTS
FOR ()-[r:ACTED_IN]-() ON (r.roles);
Text indexes
Backs only CONTAINS and ENDS WITH on STRING properties — predicates a range index cannot serve
efficiently, since neither anchors at the start of the value.
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/text-indexes/
CREATE TEXT INDEX movie_title_text IF NOT EXISTS
FOR (m:Movie) ON (m.title);
MATCH (m:Movie)
WHERE m.title CONTAINS "Matrix"
RETURN m.title;
Point indexes
Indexes POINT (Cartesian or WGS-84) properties for distance and bounding-box queries via
point.distance() or point.withinBBox().
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/point-indexes/
CREATE POINT INDEX venue_location_point IF NOT EXISTS
FOR (v:Venue) ON (v.location);
MATCH (v:Venue)
WHERE point.distance(v.location, point({latitude: 51.5, longitude: -0.12})) < 5000
RETURN v.name;
Composite indexes
A single range, text, or point index can cover more than one property of the same label or relationship type. A composite index only helps a query that supplies a predicate on every indexed property together — a predicate on just one of them falls back to a label scan.
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/range-indexes/#range-indexes-composite
CREATE INDEX person_name_born_composite IF NOT EXISTS
FOR (p:Person) ON (p.name, p.born);
MATCH (p:Person)
WHERE p.name = "Keanu Reeves" AND p.born = 1964
RETURN p;
Full-text indexes
A Lucene-backed inverted index over one or more STRING properties, queried through the
db.index.fulltext.queryNodes/queryRelationships procedures rather than a WHERE predicate. It
supports tokenized, relevance-scored search — word and phrase matching, fuzzy terms, boosting — and
can span several labels and properties at once.
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/
CREATE FULLTEXT INDEX movie_search_fulltext IF NOT EXISTS
FOR (m:Movie|Person) ON EACH [m.title, m.name, m.tagline];
CALL db.index.fulltext.queryNodes("movie_search_fulltext", "matrix OR keanu")
YIELD node, score
RETURN node.title, node.name, score
ORDER BY score DESC;
Vector indexes
Indexes a LIST<FLOAT> embedding property for approximate nearest-neighbour similarity search — the property Neo4j’s GraphRAG and semantic-search patterns build on. vector.dimensions must match
the embedding model’s output size, and vector.similarity_function is typically cosine or
euclidean.
// https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/vector-indexes/
CREATE VECTOR INDEX movie_plot_embedding IF NOT EXISTS
FOR (m:Movie) ON (m.plotEmbedding)
OPTIONS {indexConfig: {
`vector.dimensions`: 1536,
`vector.similarity_function`: "cosine"
}};
Creating the index is all this page covers — for querying it, see
Vector Search & GenAI, which uses the current Cypher
SEARCH clause rather than the older db.index.vector.queryNodes procedure.
Constraints
A constraint is a schema rule enforced on every write, independent of whether it also happens to create an index.
Uniqueness constraints
Rejects a write that would give two nodes with the same label (or two relationships with the same
type) equal values for the constrained property or property combination. It also creates a backing
range index, so IF NOT EXISTS guards against redefining one that a plain index already covers.
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#create-property-uniqueness-constraints
CREATE CONSTRAINT person_email_unique IF NOT EXISTS
FOR (p:Person) REQUIRE p.email IS UNIQUE;
Property existence constraints
Rejects a write that would leave the constrained property missing on a node with the given label, or on a relationship of the given type. Community Edition supports existence constraints only on relationship properties; node property existence constraints require Enterprise Edition.
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#create-property-existence-constraints
CREATE CONSTRAINT person_name_exists IF NOT EXISTS
FOR (p:Person) REQUIRE p.name IS NOT NULL;
CREATE CONSTRAINT acted_in_roles_exists IF NOT EXISTS
FOR ()-[r:ACTED_IN]-() REQUIRE r.roles IS NOT NULL;
Node key constraints
The multi-property, Enterprise-only combination of uniqueness and existence: every node with the given label must carry all of the listed properties, and no two such nodes may share the same combination of values — the closest Cypher equivalent of a relational composite primary key.
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#create-node-key-constraints
CREATE CONSTRAINT order_line_key IF NOT EXISTS
FOR (l:OrderLine) REQUIRE (l.orderId, l.lineNumber) IS NODE KEY;
Relationship key and property type constraints
Neo4j 5 added the relationship-side counterpart of a node key — IS RELATIONSHIP KEY — plus
IS TYPED constraints that pin a property to a single Cypher type, both Enterprise-only.
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#create-relationship-key-constraints
CREATE CONSTRAINT rated_key IF NOT EXISTS
FOR ()-[r:RATED]-() REQUIRE (r.userId, r.movieId) IS RELATIONSHIP KEY;
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#create-property-type-constraints
CREATE CONSTRAINT person_born_typed IF NOT EXISTS
FOR (p:Person) REQUIRE p.born IS :: INTEGER;
Inspecting and removing schema objects
SHOW INDEXES and SHOW CONSTRAINTS list every schema object with its name, type, entity, and
properties — including the implicit indexes a uniqueness or node-key constraint created. Both accept
YIELD to project specific columns, and a WHERE clause to filter.
// https://neo4j.com/docs/cypher-manual/current/indexes/syntax/#indexes-list-indexes
SHOW INDEXES YIELD name, type, entityType, labelsOrTypes, properties, state;
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#constraints-list-constraints
SHOW CONSTRAINTS YIELD name, type, entityType, labelsOrTypes, properties;
Drop either by the name shown in those results — IF EXISTS makes the drop idempotent, and dropping
a uniqueness or node-key constraint also drops its backing index.
// https://neo4j.com/docs/cypher-manual/current/indexes/syntax/#indexes-drop-index
DROP INDEX person_born_range IF EXISTS;
// https://neo4j.com/docs/cypher-manual/current/constraints/managing-constraints/#constraints-drop-constraint
DROP CONSTRAINT person_email_unique IF EXISTS;
Related pages
-
Indexes — the full index reference this page summarizes.
-
Semantic indexes — the range, text, and point index kinds in depth.
-
Vector indexes — dimensions, similarity functions, and querying an embedding index.
-
Elasticsearch Reference — an indexing model built the opposite way round: every document is indexed by default rather than opted in per property.
-
MongoDB Reference — secondary indexes over a document collection, for contrast with indexing a property graph.