Indexes for search performance

This section explains how to manage indexes used for search performance.

For query performance purposes, it is important to also understand how the indexes are used by the Cypher® planner. Refer to Query tuning for examples and in-depth discussions on how query plans result from different index and query scenarios. See specifically The use of indexes for examples of how various index scenarios result in different query plans.

For information on index configuration and limitations, refer to Operations Manual → Index configuration.

Indexes (types and limitations)

A database index is a redundant copy of some of the data in the database for the purpose of making searches of related data more efficient. This comes at the cost of additional storage space and slower writes, so deciding what to index and what not to index is an important and often non-trivial task.

Once an index has been created, it will be managed and kept up to date by the DBMS. Neo4j will automatically pick up and start using the index once it has been created and brought online.

There are multiple index types available: B-tree (deprecated), fulltext, lookup, and text index types. See Full-text search index for more information about fulltext indexes. Token lookup indexes contain nodes with one or more labels or relationship types, without regard for any properties.

Cypher enables the creation of B-tree indexes on one or more properties for all nodes or relationships with a given label or relationship type:

  • An index created on a single property for any given label or relationship type is called a single-property index.

  • An index created on more than one property for any given label or relationship type is called a composite index.

Differences in the usage patterns between composite and single-property indexes are described in Composite index limitations.

Additionally, a text index is a kind of single-property index, with the limitation that it only recognizes properties with string values. Nodes or relationships with the indexed label or relationship type where the indexed property is of another value type are not included in the index.

The following is true for indexes:

  • Best practice is to give the index a name when it is created. If the index is not explicitly named, it gets an auto-generated name.

  • The index name must be unique among both indexes and constraints.

  • Index creation is by default not idempotent, and an error will be thrown if you attempt to create the same index twice. Using the keyword IF NOT EXISTS makes the command idempotent, and no error will be thrown if you attempt to create the same index twice.

Syntax

The index name must be unique among both indexes and constraints.

Best practice is to give the index a name when it is created. If the index is not explicitly named, it gets an auto-generated name.

The CREATE ... INDEX ... command is optionally idempotent, with the default behavior to throw an error if you attempt to create the same index twice. With IF NOT EXISTS, no error is thrown and nothing happens should an index with the same name or same schema and index type already exist. It may still throw an error if conflicting constraints exist, such as constraints with the same name or schema and backing index type.

More details about the syntax descriptions can be found here.

Table 1. Create a single-property index on nodes Deprecated

Syntax

CREATE [BTREE] INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a single-property index on nodes.

Index provider and configuration can be specified using the OPTIONS clause.

Note

Explicit use of BTREE keyword or B-tree options are deprecated in 4.4 and will be replaced in 5.0.

Table 2. Create a single-property index on relationships Deprecated

Syntax

CREATE [BTREE] INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r:TYPE_NAME"]"-()
ON (r.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a single-property index on relationships.

Index provider and configuration can be specified using the OPTIONS clause.

Note

Explicit use of BTREE keyword or B-tree options are deprecated in 4.4 and will be replaced in 5.0.

Table 3. Create a composite index on nodes Deprecated

Syntax

CREATE [BTREE] INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName_1,
    n.propertyName_2,
    ...
    n.propertyName_n)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a composite index on nodes.

Index provider and configuration can be specified using the OPTIONS clause.

Note

Explicit use of BTREE keyword or B-tree options are deprecated in 4.4 and will be replaced in 5.0.

Table 4. Create a composite index on relationships Deprecated

Syntax

CREATE [BTREE] INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r:TYPE_NAME"]"-()
ON (r.propertyName_1,
    r.propertyName_2,
    ...
    r.propertyName_n)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a composite index on relationships.

Index provider and configuration can be specified using the OPTIONS clause.

Note

Explicit use of BTREE keyword or B-tree options are deprecated in 4.4 and will be replaced in 5.0.

Table 5. Create a node label lookup index

Syntax

CREATE LOOKUP INDEX [index_name] [IF NOT EXISTS]
FOR (n)
ON EACH labels(n)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a node label lookup index.

Index provider can be specified using the OPTIONS clause.

Table 6. Create a relationship type lookup index

Syntax

CREATE LOOKUP INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r"]"-()
ON [EACH] type(r)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a relationship type lookup index.

Index provider can be specified using the OPTIONS clause.

Table 7. Create a text index on nodes

Syntax

CREATE TEXT INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a text index on nodes where the property has a string value.

Index provider can be specified using the OPTIONS clause.

Table 8. Create a text index on relationships

Syntax

CREATE TEXT INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r:TYPE_NAME"]"-()
ON (r.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a text index on relationships where the property has a string value.

Index provider can be specified using the OPTIONS clause.

Table 9. Drop an index

Syntax

DROP INDEX index_name [IF EXISTS]

Description

Drop an index of any index type.

Note

The command is optionally idempotent, with the default behavior to throw an error if you attempt to drop the same index twice. With IF EXISTS, no error is thrown and nothing happens should the index not exist.

Table 10. Drop a single-property index Deprecated

Syntax

DROP INDEX ON :LabelName(propertyName)

Description

Drop a single-property index on nodes without specifying a name.

Note

This syntax is deprecated.

Table 11. Drop a composite index Deprecated

Syntax

DROP INDEX ON :LabelName (n.propertyName_1,
n.propertyName_2,
...
n.propertyName_n)

Description

Drop a composite index on nodes without specifying a name.

Note

This syntax is deprecated.

Table 12. List indexes

Syntax

SHOW [ALL | BTREE | FULLTEXT | LOOKUP | TEXT] INDEX[ES]
  [YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
  [WHERE expression]
  [RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]

Description

List indexes in the database, either all or filtered on index type.

Note

When using the RETURN clause, the YIELD clause is mandatory and must not be omitted.

Creating an index requires the CREATE INDEX privilege, while dropping an index requires the DROP INDEX privilege and listing indexes require the SHOW INDEX privilege.

Planner hints and the USING keyword describes how to make the Cypher planner use specific indexes (especially in cases where the planner would not necessarily have used them).

Composite index limitations

Like single-property B-tree indexes, composite B-tree indexes support all predicates:

  • equality check: n.prop = value

  • list membership check: n.prop IN list

  • existence check: n.prop IS NOT NULL

  • range search: n.prop > value

  • prefix search: STARTS WITH

  • suffix search: ENDS WITH

  • substring search: CONTAINS

For details about each operator, see Operators.

However, predicates might be planned as existence check and a filter. For most predicates, this can be avoided by following these restrictions:

  • If there is any equality check and list membership check predicates, they need to be for the first properties defined by the index.

  • There can be up to one range search or prefix search predicate.

  • There can be any number of existence check predicates.

  • Any predicate after a range search, prefix search or existence check predicate has to be an existence check predicate.

However, the suffix search and substring search predicates are always planned as existence check and a filter and any predicates following after will therefore also be planned as such.

For example, an index on nodes with :Label(prop1,prop2,prop3,prop4,prop5,prop6) and predicates:

WHERE n.prop1 = 'x' AND n.prop2 = 1 AND n.prop3 > 5 AND n.prop4 < 'e' AND n.prop5 = true AND n.prop6 IS NOT NULL

will be planned as:

WHERE n.prop1 = 'x' AND n.prop2 = 1 AND n.prop3 > 5 AND n.prop4 IS NOT NULL AND n.prop5 IS NOT NULL AND n.prop6 IS NOT NULL

with filters on n.prop4 < 'e' and n.prop5 = true, since n.prop3 has a range search predicate.

And an index on nodes with :Label(prop1,prop2) with predicates:

WHERE n.prop1 ENDS WITH 'x' AND n.prop2 = false

will be planned as:

WHERE n.prop1 IS NOT NULL AND n.prop2 IS NOT NULL

with filters on n.prop1 ENDS WITH 'x' and n.prop2 = false, since n.prop1 has a suffix search predicate.

Composite indexes require predicates on all properties indexed. If there are predicates on only a subset of the indexed properties, it will not be possible to use the composite index. To get this kind of fallback behavior, it is necessary to create additional indexes on the relevant sub-set of properties or on single properties.

CREATE INDEX examples

Create a single-property B-tree index for nodes

A named B-tree index on a single property for all nodes with a particular label can be created with:

CREATE [BTREE] INDEX index_name FOR (n:Label) ON (n.property)

The index is not immediately available, but is created in the background.

Example 1. CREATE BTREE INDEX
Query
CREATE INDEX node_index_name FOR (n:Person) ON (n.name)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a single-property B-tree index for relationships

A named B-tree index on a single property for all relationships with a particular relationship type can be created with:

CREATE [BTREE] INDEX index_name FOR ()-[r:TYPE]-() ON (r.property)

The index is not immediately available, but is created in the background.

Example 2. CREATE BTREE INDEX
Query
CREATE INDEX rel_index_name FOR ()-[r:KNOWS]-() ON (r.since)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a single-property B-tree index only if it does not already exist

If it is not known whether an index exists or not, add IF NOT EXISTS to ensure it does.

Example 3. CREATE BTREE INDEX
Query
CREATE INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname)

Note that the index will not be created if there already exists an index with the same schema and type, same name or both.

Result
+--------------------------------------------+
| No data returned, and nothing was changed. |
+--------------------------------------------+

Create a single-property B-tree index with specified index provider Deprecated

To create a single property B-tree index with a specific index provider, the OPTIONS clause is used. Valid values for the index provider are native-btree-1.0 and lucene+native-3.0, default is native-btree-1.0.

Example 4. CREATE BTREE INDEX
Query
CREATE BTREE INDEX index_with_provider FOR ()-[r:TYPE]-() ON (r.prop1)
OPTIONS {indexProvider: 'native-btree-1.0'}

Can be combined with specifying index configuration.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a single-property B-tree index with specified index configuration Deprecated

To create a single property B-tree index with a specific index configuration, the OPTIONS clause is used.

The valid configuration settings are:

  • spatial.cartesian.min

  • spatial.cartesian.max

  • spatial.cartesian-3d.min

  • spatial.cartesian-3d.max

  • spatial.wgs-84.min

  • spatial.wgs-84.max

  • spatial.wgs-84-3d.min

  • spatial.wgs-84-3d.max

Non-specified settings have their respective default values.

Example 5. CREATE BTREE INDEX
Query
CREATE BTREE INDEX index_with_config FOR (n:Label) ON (n.prop2)
OPTIONS {
  indexConfig: {
    `spatial.cartesian.min`: [-100.0, -100.0],
    `spatial.cartesian.max`: [100.0, 100.0]
  }
}

Can be combined with specifying index provider.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a composite B-tree index for nodes

A named B-tree index on multiple properties for all nodes with a particular label — i.e. a composite index — can be created with:

CREATE INDEX index_name FOR (n:Label) ON (n.prop1, ..., n.propN)

Only nodes with the specified label and that contain all the properties in the index definition will be added to the index.

The composite index is not immediately available, but is created in the background.

Example 6. CREATE BTREE INDEX

The following statement will create a named composite index on all nodes labeled with Person and which have both an age and country property:

Query
CREATE INDEX node_index_name FOR (n:Person) ON (n.age, n.country)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a composite B-tree index for relationships

A named B-tree index on multiple properties for all relationships with a particular relationship type — i.e. a composite index — can be created with CREATE INDEX index_name FOR ()-[r:TYPE]-() ON (r.prop1, ..., r.propN). Only relationships with the specified type and that contain all the properties in the index definition will be added to the index. Note that the composite index is not immediately available, but is created in the background.

Example 7. CREATE BTREE INDEX

The following statement will create a named composite index on all relationships labeled with PURCHASED and which have both a date and amount property:

Query
CREATE INDEX rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a composite B-tree index with specified index provider and configuration Deprecated

To create a composite B-tree index with a specific index provider and configuration, the OPTIONS clause is used. Valid values for the index provider are native-btree-1.0 and lucene+native-3.0, default is native-btree-1.0. The valid configuration settings are:

  • spatial.cartesian.min

  • spatial.cartesian.max

  • spatial.cartesian-3d.min

  • spatial.cartesian-3d.max

  • spatial.wgs-84.min

  • spatial.wgs-84.max

  • spatial.wgs-84-3d.min

  • spatial.wgs-84-3d.max

Non-specified settings have their respective default values.

Example 8. CREATE BTREE INDEX
Query
CREATE INDEX index_with_options FOR (n:Label) ON (n.prop1, n.prop2)
OPTIONS {
 indexProvider: 'lucene+native-3.0',
 indexConfig: {
   `spatial.wgs-84.min`: [-100.0, -80.0],
   `spatial.wgs-84.max`: [100.0, 80.0]
  }
}

Specifying index provider and configuration can be done individually.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a node label lookup index

A named token lookup index for all nodes with one or more labels can be created with:

CREATE LOOKUP INDEX index_name FOR (n) ON EACH labels(n)

The index is not immediately available, but is created in the background.

Example 9. CREATE LOOKUP INDEX
Query
CREATE LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n)

Note that it can only be created once and that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a relationship type lookup index

A named token lookup index for all relationships with any relationship type can be created with:

CREATE LOOKUP INDEX index_name FOR ()-[r]-() ON EACH type(r)

The index is not immediately available, but is created in the background.

Example 10. CREATE LOOKUP INDEX
Query
CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r)

Note that it can only be created once and that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a token lookup index specifying the index provider

Token lookup indexes allow setting the index provider using the OPTIONS clause. Only one valid value exists for the index provider, token-lookup-1.0, which is the default value.

Example 11. CREATE LOOKUP INDEX
Query
CREATE LOOKUP INDEX node_label_lookup_index_2 FOR (n) ON EACH labels(n)
OPTIONS {indexProvider: 'token-lookup-1.0'}

There is no supported index configuration for token lookup indexes.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a node text index

A named text index on a single property for all nodes with a particular label can be created with: Text indexes only recognize string values, do not support multiple properties, and that the index name must be unique.

CREATE TEXT INDEX index_name FOR (n:Label) ON (n.property)

The index is not immediately available, but is created in the background.

Example 12. CREATE TEXT INDEX
Query
CREATE TEXT INDEX node_index_name FOR (n:Person) ON (n.nickname)
Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a relationship text index

A named text index on a single property for all relationships with a particular relationship type can be created with:

CREATE TEXT INDEX index_name FOR ()-[r:TYPE]-() ON (r.property)

The index is not immediately available, but is created in the background.

Example 13. CREATE TEXT INDEX
Query
CREATE TEXT INDEX rel_index_name FOR ()-[r:KNOWS]-() ON (r.interest)

Note that text indexes only recognize string values, do not support multiple properties, and that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a text index only if it does not already exist

If it is not known whether an index exists or not, add IF NOT EXISTS to ensure it does.

Example 14. CREATE TEXT INDEX
Query
CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname)

Note that the index will not be created if there already exists an index with the same schema and type, same name or both.

Result
+--------------------------------------------+
| No data returned, and nothing was changed. |
+--------------------------------------------+

Create a text index specifying the index provider

To create a text index with a specific index provider, the OPTIONS clause is used. Only one valid value exists for the index provider, text-1.0, which is the default value.

Example 15. CREATE TEXT INDEX
Query
CREATE TEXT INDEX index_with_provider FOR ()-[r:TYPE]-() ON (r.prop1)
OPTIONS {indexProvider: 'text-1.0'}

There is no supported index configuration for text indexes.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Failure to create an already existing index

Create an index on the property title on nodes with the Book label, when that index already exists.

Example 16. CREATE BTREE INDEX
Query
CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title)

In this case the index can not be created because it already exists.

Error message
There already exists an index (:Book {title}).

Failure to create an index with the same name as an already existing index

Create a named index on the property numberOfPages on nodes with the Book label, when an index with that name already exists.

Example 17. CREATE BTREE INDEX
Query
CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages)

In this case the index can’t be created because there already exists an index with that name.

Error message
There already exists an index called 'indexOnBooks'.

Failure to create an index when a constraint already exists

Create an index on the property isbn on nodes with the Book label, when an index-backed constraint already exists on that schema.

Example 18. CREATE BTREE INDEX
Query
CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn)

In this case the index can not be created because a index-backed constraint already exists on that label and property combination.

Error message
There is a uniqueness constraint on (:Book {isbn}), so an index is already created that matches this.

Failure to create an index with the same name as an already existing constraint

Create a named index on the property numberOfPages on nodes with the Book label, when a constraint with that name already exists.

Example 19. CREATE BTREE INDEX
Query
CREATE INDEX bookRecommendations FOR (book:Book) ON (book.recommendations)

In this case the index can not be created because there already exists a constraint with that name.

Error message
There already exists a constraint called 'bookRecommendations'.

SHOW INDEXES

Listing indexes can be done with SHOW INDEXES, which will produce a table with the following columns:

The command SHOW INDEXES returns only the default output. For a full output use the optional YIELD command. Full output: SHOW INDEXES YIELD *.

Table 13. List indexes output
Column Description

id

The id of the index. Default Output

name

Name of the index (explicitly set by the user or automatically assigned). Default Output

state

Current state of the index. Default Output

populationPercent

% of index population. Default Output

uniqueness

Tells if the index is only meant to allow one value per key. Default Output

type

The IndexType of this index (BTREE, FULLTEXT, LOOKUP, or TEXT). Default Output

entityType

Type of entities this index represents (nodes or relationship). Default Output

labelsOrTypes

The labels or relationship types of this index. Default Output

properties

The properties of this index. Default Output

indexProvider

The index provider for this index. Default Output

options

The options passed to CREATE command.

failureMessage

The failure description of a failed index.

createStatement

Statement used to create the index.

Listing indexes also allows for WHERE and YIELD clauses to filter the returned rows and columns.

While the command for listing indexes require the SHOW INDEX privilege, the deprecated built-in procedures for listing indexes, such as db.indexes, work as before and are not affected by the privilege.

SHOW INDEXES examples

Listing all indexes

To list all indexes with the default output columns, the SHOW INDEXES command can be used. If all columns are required, use SHOW INDEXES YIELD *.

Example 20. SHOW INDEXES
Query
SHOW INDEXES

One of the output columns from SHOW INDEXES is the name of the index. This can be used to drop the index with the DROP INDEX command.

Result
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name             | state    | populationPercent | uniqueness  | type    | entityType | labelsOrTypes | properties     | indexProvider      |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| 4  | "index_44d2128f" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"     | ["Person"]    | ["middlename"] | "native-btree-1.0" |
| 7  | "index_58a1c03e" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"     | ["Person"]    | ["location"]   | "native-btree-1.0" |
| 5  | "index_763f72db" | "ONLINE" | 100.0             | "NONUNIQUE" | "TEXT"  | "NODE"     | ["Person"]    | ["middlename"] | "text-1.0"         |
| 8  | "index_d7c12ba3" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"     | ["Person"]    | ["highScore"]  | "native-btree-1.0" |
| 3  | "index_deeafdb2" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"     | ["Person"]    | ["firstname"]  | "native-btree-1.0" |
| 6  | "index_eadb868e" | "ONLINE" | 100.0             | "NONUNIQUE" | "TEXT"  | "NODE"     | ["Person"]    | ["surname"]    | "text-1.0"         |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
6 rows

Listing indexes with filtering

One way of filtering the output from SHOW INDEXES by index type is the use of type keywords, listed in the syntax table. For example, to show only B-tree indexes, use SHOW BTREE INDEXES. Another more flexible way of filtering the output is to use the WHERE clause. An example is to only show indexes not belonging to constraints.

Example 21. SHOW BTREE INDEXES
Query
SHOW BTREE INDEXES WHERE uniqueness = 'NONUNIQUE'

This will only return the default output columns. To get all columns, use SHOW INDEXES YIELD * WHERE ....

Result
+-----------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name             | state    | populationPercent | uniqueness  | type    | entityType     | labelsOrTypes | properties     | indexProvider      |
+-----------------------------------------------------------------------------------------------------------------------------------------------------+
| 4  | "index_44d2128f" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"         | ["Person"]    | ["middlename"] | "native-btree-1.0" |
| 7  | "index_58a1c03e" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"         | ["Person"]    | ["location"]   | "native-btree-1.0" |
| 9  | "index_c207e3e6" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "RELATIONSHIP" | ["KNOWS"]     | ["since"]      | "native-btree-1.0" |
| 8  | "index_d7c12ba3" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"         | ["Person"]    | ["highScore"]  | "native-btree-1.0" |
| 3  | "index_deeafdb2" | "ONLINE" | 100.0             | "NONUNIQUE" | "BTREE" | "NODE"         | ["Person"]    | ["firstname"]  | "native-btree-1.0" |
+-----------------------------------------------------------------------------------------------------------------------------------------------------+
5 rows

DROP INDEX

An index can be dropped (removed) using the name with the DROP INDEX index_name command. This command can drop indexes of any type, except those backing constraints. The name of the index can be found using the SHOW INDEXES command, given in the output column name.

DROP INDEX examples

Drop an index

Example 22. DROP INDEX
Query
DROP INDEX index_name
Result
+-------------------+
| No data returned. |
+-------------------+
Indexes removed: 1

Drop a non-existing index

If it is uncertain if an index exists and you want to drop it if it does but not get an error should it not, use IF EXISTS.

Example 23. DROP INDEX
Query
DROP INDEX missing_index_name IF EXISTS
Result
+--------------------------------------------+
| No data returned, and nothing was changed. |
+--------------------------------------------+

Future indexes

Two new types of indexes, point and range indexes, will be introduced in a future release. They cannot be used in queries yet, but they can be created and dropped for migration purposes. These new index types together with text indexes will replace the current B-tree indexes. For more details on these new types, see the Operations Manual → Future indexes.

Like B-tree indexes, range indexes are created on one or more properties for all nodes or relationships with a given label or relationship type:

  • An index created on a single property for any given label or relationship type is called a single-property index.

  • An index created on more than one property for any given label or relationship type is called a composite index.

The differences in the usage patterns between composite and single-property indexes described in Composite index limitations also applies to range indexes.

Similar to B-tree indexes, range indexes may also back constraints by giving the range index provider when creating an index-backed constraint.

Point indexes, like text indexes, are a kind of single-property indexes, with the limitation that they only recognize properties with point values. Nodes or relationships with the indexed label or relationship type where the indexed property is of another value type are not included in the index.

Syntax

The index name must be unique among both indexes and constraints.

Best practice is to give the index a name when it is created. If the index is not explicitly named, it gets an auto-generated name.

The CREATE ... INDEX ... command is optionally idempotent, with the default behavior to throw an error if you attempt to create the same index twice. With IF NOT EXISTS, no error is thrown and nothing happens should an index with the same name or same schema and index type already exist. It may still throw an error if conflicting constraints exist, such as constraints with the same name or schema and backing index type.

Table 14. Create a range index on nodes

Syntax

CREATE RANGE INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName_1[,
    n.propertyName_2,
    ...
    n.propertyName_n])
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a range index on nodes, either on a single property or composite.

Index provider can be specified using the OPTIONS clause.

Table 15. Create a range index on relationships

Syntax

CREATE RANGE INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r:TYPE_NAME"]"-()
ON (r.propertyName_1[,
    r.propertyName_2,
    ...
    r.propertyName_n])
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a range index on relationships, either on a single property or composite.

Index provider can be specified using the OPTIONS clause.

Table 16. Create a point index on nodes

Syntax

CREATE POINT INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a point index on nodes where the property has a point value.

Index provider and configuration can be specified using the OPTIONS clause.

Table 17. Create a point index on relationships

Syntax

CREATE POINT INDEX [index_name] [IF NOT EXISTS]
FOR ()-"["r:TYPE_NAME"]"-()
ON (r.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

Description

Create a point index on relationships where the property has a point value.

Index provider and configuration can be specified using the OPTIONS clause.

Table 18. Drop an index

Syntax

DROP INDEX index_name [IF EXISTS]

Description

Drop an index of any index type.

This is the same command as for the existing indexes.

Note

The command is optionally idempotent, with the default behavior to throw an error if you attempt to drop the same index twice. With IF EXISTS, no error is thrown and nothing happens should the index not exist.

Table 19. List indexes

Syntax

SHOW [ALL | BTREE | FULLTEXT | LOOKUP | POINT | RANGE | TEXT] INDEX[ES]
  [YIELD { * | field[, ...] } [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]
  [WHERE expression]
  [RETURN field[, ...] [ORDER BY field[, ...]] [SKIP n] [LIMIT n]]

Description

Extending the existing list index command with filters for the new types.

Note

When using the RETURN clause, the YIELD clause is mandatory and must not be omitted.

Examples

Create a single-property range index for nodes

A named range index on a single property for all nodes with a particular label can be created with:

CREATE RANGE INDEX index_name FOR (n:Label) ON (n.property)

The index is not immediately available, but is created in the background.

Example 24. CREATE RANGE INDEX
Query
CREATE RANGE INDEX node_range_index_name FOR (n:Person) ON (n.surname)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a single-property range index for relationships

A named range index on a single property for all relationships with a particular relationship type can be created with:

CREATE RANGE INDEX index_name FOR ()-[r:TYPE]-() ON (r.property)

The index is not immediately available, but is created in the background.

Example 25. CREATE RANGE INDEX
Query
CREATE RANGE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a range index only if it does not already exist

If it is not known whether an index exists or not, add IF NOT EXISTS to ensure it does.

Example 26. CREATE RANGE INDEX
Query
CREATE RANGE INDEX node_range_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname)

Note that the index will not be created if there already exists an index with the same schema and type, same name or both.

Result
+--------------------------------------------+
| No data returned, and nothing was changed. |
+--------------------------------------------+

Create a range index specifying the index provider

To create a range index with a specific index provider, the OPTIONS clause is used. Only one valid value exists for the index provider, range-1.0, which is the default value.

Example 27. CREATE RANGE INDEX
Query
CREATE RANGE INDEX range_index_with_provider FOR ()-[r:TYPE]-() ON (r.prop1)
OPTIONS {indexProvider: 'range-1.0'}

There is no supported index configuration for range indexes.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a composite range index for nodes

A named range index on multiple properties for all nodes with a particular label — i.e. a composite index — can be created with:

CREATE RANGE INDEX index_name FOR (n:Label) ON (n.prop1, ..., n.propN)

Only nodes with the specified label and that contain all the properties in the index definition will be added to the index.

The composite index is not immediately available, but is created in the background.

Example 28. CREATE RANGE INDEX

The following statement will create a named composite range index on all nodes labeled with Person and which have both an age and country property:

Query
CREATE RANGE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a composite range index for relationships

A named range index on multiple properties for all relationships with a particular relationship type — i.e. a composite index — can be created with:

CREATE RANGE INDEX index_name FOR ()-[r:TYPE]-() ON (r.prop1, ..., r.propN)

Only relationships with the specified type and that contain all the properties in the index definition will be added to the index.

The composite index is not immediately available, but is created in the background.

Example 29. CREATE RANGE INDEX

The following statement will create a named composite range index on all relationships labeled with PURCHASED and which have both a date and amount property:

Query
CREATE RANGE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount)

Note that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a node point index

A named point index on a single property for all nodes with a particular label can be created with:

CREATE POINT INDEX index_name FOR (n:Label) ON (n.property)

The index is not immediately available, but is created in the background.

Example 30. CREATE POINT INDEX
Query
CREATE POINT INDEX node_index_name FOR (n:Person) ON (n.location)

Note that point indexes only recognize point values, do not support multiple properties, and that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a relationship point index

A named point index on a single property for all relationships with a particular relationship type can be created with:

CREATE POINT INDEX index_name FOR ()-[r:TYPE]-() ON (r.property)

The index is not immediately available, but is created in the background.

Example 31. CREATE POINT INDEX
Query
CREATE POINT INDEX rel_index_name FOR ()-[r:STREET]-() ON (r.intersection)

Note that point indexes only recognize point values, do not support multiple properties, and that the index name must be unique.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a point index only if it does not already exist

If it is not known whether an index exists or not, add IF NOT EXISTS to ensure it does.

Example 32. CREATE POINT INDEX
Query
CREATE POINT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.location)

Note that the index will not be created if there already exists an index with the same schema and type, same name or both.

Result
+--------------------------------------------+
| No data returned, and nothing was changed. |
+--------------------------------------------+

Create a point index specifying the index provider

To create a point index with a specific index provider, the OPTIONS clause is used. Only one valid value exists for the index provider, point-1.0, which is the default value.

Example 33. CREATE POINT INDEX
Query
CREATE POINT INDEX index_with_provider FOR (n:Label) ON (n.prop1)
OPTIONS {indexProvider: 'point-1.0'}

Can be combined with specifying index configuration.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a point index specifying the index configuration

To create a point index with a specific index configuration, the OPTIONS clause is used. The valid configuration settings are:

  • spatial.cartesian.min

  • spatial.cartesian.max

  • spatial.cartesian-3d.min

  • spatial.cartesian-3d.max

  • spatial.wgs-84.min

  • spatial.wgs-84.max

  • spatial.wgs-84-3d.min

  • spatial.wgs-84-3d.max

Non-specified settings have their respective default values.

Example 34. CREATE POINT INDEX
Query
CREATE POINT INDEX index_with_config FOR (n:Label) ON (n.prop2)
OPTIONS {
  indexConfig: {
    `spatial.cartesian.min`: [-100.0, -100.0],
    `spatial.cartesian.max`: [100.0, 100.0]
  }
}

Can be combined with specifying index provider.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Create a point index specifying both the index provider and configuration

To create a point index with a specific index provider and configuration, the OPTIONS clause is used. Only one valid value exists for the index provider, point-1.0, which is the default value. The valid configuration settings are:

  • spatial.cartesian.min

  • spatial.cartesian.max

  • spatial.cartesian-3d.min

  • spatial.cartesian-3d.max

  • spatial.wgs-84.min

  • spatial.wgs-84.max

  • spatial.wgs-84-3d.min

  • spatial.wgs-84-3d.max

Non-specified settings have their respective default values.

Example 35. CREATE POINT INDEX
Query
CREATE POINT INDEX index_with_options FOR ()-[r:TYPE]-() ON (r.prop1)
OPTIONS {
  indexProvider: 'point-1.0',
  indexConfig: {
    `spatial.wgs-84.min`: [-100.0, -80.0],
    `spatial.wgs-84.max`: [100.0, 80.0]
  }
}

Specifying index provider and configuration can be done individually.

Result
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1

Deprecated syntax

This syntax only supports dropping B-tree node property indexes, all others can only be dropped by name.

Drop a single-property index

A B-tree index on all nodes with a label and single property combination can be dropped with:

DROP INDEX ON :Label(property)
Example 36. DROP INDEX
Query
DROP INDEX ON :Person(firstname)
Result
+-------------------+
| No data returned. |
+-------------------+
Indexes removed: 1

Drop a composite index

A composite B-tree index on all nodes with a label and multiple property combination can be dropped with:

DROP INDEX ON :Label(prop1, ..., propN)
Example 37. DROP INDEX

The following statement will drop a composite index on all nodes labeled with Person and which have both an age and country property:

Query
DROP INDEX ON :Person(age, country)
Result
+-------------------+
| No data returned. |
+-------------------+
Indexes removed: 1