diff --git a/modules/ROOT/content-nav.adoc b/modules/ROOT/content-nav.adoc index e07c65db3..c9940d969 100644 --- a/modules/ROOT/content-nav.adoc +++ b/modules/ROOT/content-nav.adoc @@ -110,7 +110,9 @@ * xref:genai-integrations.adoc[] * xref:indexes/index.adoc[] ** xref:indexes/search-performance-indexes/index.adoc[] -*** xref:indexes/search-performance-indexes/managing-indexes.adoc[] +*** xref:indexes/search-performance-indexes/create-indexes.adoc[] +*** xref:indexes/search-performance-indexes/list-indexes.adoc[] +*** xref:indexes/search-performance-indexes/drop-indexes.adoc[] *** xref:indexes/search-performance-indexes/using-indexes.adoc[] *** xref:indexes/search-performance-indexes/index-hints.adoc[] ** xref:indexes/semantic-indexes/index.adoc[] diff --git a/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc b/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc index 04bf0de57..591eef117 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/additional-cypher.adoc @@ -582,19 +582,19 @@ If the points are in a Cartesian CRS, the function returns the Euclidean distanc | Cypher feature | Description -| xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[Range indexes] +| xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[Range indexes] | Neo4j’s default index. Supports most types of predicates. -| xref:indexes/search-performance-indexes/managing-indexes.adoc#create-text-index[Text indexes] +| xref:indexes/search-performance-indexes/create-indexes.adoc#create-text-index[Text indexes] | Solves predicates operating on `STRING` values. Optimized for queries filtering with the `STRING` operators `CONTAINS` and `ENDS WITH`. -| xref:indexes/search-performance-indexes/managing-indexes.adoc#create-point-index[Point indexes] +| xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[Point indexes] | Solves predicates on spatial `POINT` values. Optimized for queries filtering on distance or within bounding boxes. -| xref:indexes/search-performance-indexes/managing-indexes.adoc#create-lookup-index[Token lookup indexes] +| xref:indexes/search-performance-indexes/create-indexes.adoc#create-lookup-index[Token lookup indexes] | Only solves node label and relationship type predicates (i.e. they cannot solve any predicates filtering on properties). | xref:indexes/semantic-indexes/full-text-indexes.adoc#create-full-text-indexes[Full text indexes] diff --git a/modules/ROOT/pages/appendix/tutorials/advanced-query-tuning.adoc b/modules/ROOT/pages/appendix/tutorials/advanced-query-tuning.adoc index 5d5816465..2c72971d1 100644 --- a/modules/ROOT/pages/appendix/tutorials/advanced-query-tuning.adoc +++ b/modules/ROOT/pages/appendix/tutorials/advanced-query-tuning.adoc @@ -5,7 +5,7 @@ This page describes advanced query optimizations based on native index capabilities. One of the most important and useful ways of optimizing Cypher queries involves creating appropriate indexes. -This is described in more detail in xref:indexes/search-performance-indexes/managing-indexes.adoc[], and demonstrated in xref::appendix/tutorials/basic-query-tuning.adoc[]. +This is described in more detail in xref:indexes/search-performance-indexes/create-indexes.adoc[], and demonstrated in xref::appendix/tutorials/basic-query-tuning.adoc[]. In summary, an index will be based on the combination of a `Label` and a `property`. Any Cypher query that searches for nodes with a specific label and some predicate on the property (equality, range or existence) will be planned to use the index if the cost planner deems that to be the most efficient solution. diff --git a/modules/ROOT/pages/appendix/tutorials/basic-query-tuning.adoc b/modules/ROOT/pages/appendix/tutorials/basic-query-tuning.adoc index faa961fe0..498a9ccaf 100644 --- a/modules/ROOT/pages/appendix/tutorials/basic-query-tuning.adoc +++ b/modules/ROOT/pages/appendix/tutorials/basic-query-tuning.adoc @@ -764,5 +764,5 @@ Total database accesses: 5, total allocated memory: 184 1 row ---- -Our execution plan is down to a single row and uses the xref::planning-and-tuning/operators/operators-detail.adoc#query-plan-node-index-seek[Node Index Seek] operator which does an index seek (see xref::indexes/search-performance-indexes/managing-indexes.adoc[]) to find the appropriate node. +Our execution plan is down to a single row and uses the xref::planning-and-tuning/operators/operators-detail.adoc#query-plan-node-index-seek[Node Index Seek] operator which does an index seek (see xref::indexes/search-performance-indexes/list-indexes.adoc[]) to find the appropriate node. diff --git a/modules/ROOT/pages/clauses/merge.adoc b/modules/ROOT/pages/clauses/merge.adoc index 6e20bd3f6..85294cf77 100644 --- a/modules/ROOT/pages/clauses/merge.adoc +++ b/modules/ROOT/pages/clauses/merge.adoc @@ -15,7 +15,7 @@ If there isn't a node with the specific `name` property, a new node will be crea [NOTE] ==== For performance reasons, creating a schema index on the label or property is highly recommended when using `MERGE`. -See xref:indexes/search-performance-indexes/managing-indexes.adoc[] for more information. +See xref:indexes/search-performance-indexes/create-indexes.adoc[] for more information. ==== When using `MERGE` on full patterns, the behavior is that either the whole pattern matches, or the whole pattern is created. diff --git a/modules/ROOT/pages/constraints/managing-constraints.adoc b/modules/ROOT/pages/constraints/managing-constraints.adoc index 84d987fa7..d72bcd6c8 100644 --- a/modules/ROOT/pages/constraints/managing-constraints.adoc +++ b/modules/ROOT/pages/constraints/managing-constraints.adoc @@ -943,7 +943,7 @@ Constraint already exists: Constraint( id=7, name='book_title_year', type='NODE [[constraints-and-backing-indexes]] ==== Constraints and backing indexes -Property uniqueness constraints and key constraints are backed by xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[range indexes]. +Property uniqueness constraints and key constraints are backed by xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[range indexes]. This means that creating a property uniqueness or key constraint will create a range index with the same name, node label/relationship type and property combination as its owning constraint. Single property constraints will create single property indexes and multiple property composite constraints will create xref:indexes/search-performance-indexes/using-indexes.adoc#composite-indexes[composite indexes]. @@ -958,7 +958,7 @@ The index makes these checks much faster by enabling direct lookups instead of s Cypher will use the indexes with an owning constraint in the same way that it utilizes other search-performance indexes. For more information about how indexes impact query performance, see xref:indexes/search-performance-indexes/using-indexes.adoc[]. -These indexes are listed in the `owningConstraint` column returned by the xref:indexes/search-performance-indexes/managing-indexes.adoc#list-indexes[`SHOW INDEX`] command, and the `ownedIndex` column returned by the xref:constraints/managing-constraints.adoc#list-constraints[`SHOW CONSTRAINT`] command. +These indexes are listed in the `owningConstraint` column returned by the xref:indexes/search-performance-indexes/list-indexes.adoc[`SHOW INDEX`] command, and the `ownedIndex` column returned by the xref:constraints/managing-constraints.adoc#list-constraints[`SHOW CONSTRAINT`] command. .List constraints with backing indexes ====== @@ -1302,7 +1302,7 @@ CREATE CONSTRAINT book_title FOR (book:Book) REQUIRE book.title IS UNIQUE ---- In this case, the constraint cannot be created because it is in conflict with the existing graph. -Either use xref:indexes/search-performance-indexes/managing-indexes.adoc[indexes] instead, or remove/correct the offending nodes and then re-apply the constraint. +Either use xref:indexes/search-performance-indexes/create-indexes.adoc[indexes] instead, or remove/correct the offending nodes and then re-apply the constraint. .Error message [source, error] diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc new file mode 100644 index 000000000..49aefe7ac --- /dev/null +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -0,0 +1,773 @@ +:description: This page explains how to create indexes used for search performance. += Create indexes + +Creating an index is done with the `CREATE [index_type] INDEX [index_name]` command. +If no index type is specified in the create command a xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[range index] is created. + +The following index types are included in this category: + +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[Range indexes] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-text-index[Text indexes] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[Point indexes] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-lookup-index[Token lookup indexes] + +It is recommended to give the index a name when it is created. +If the index is not explicitly named, it gets an auto-generated name. + +[NOTE] +==== +The index name must be unique among both indexes and constraints. +==== + +The `CREATE INDEX` command is optionally idempotent. +This mean that its default behavior is to throw an error if an attempt is made to create the same index twice. +If `IF NOT EXISTS` is appended to the command, 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. +Instead, an informational notification is returned showing the existing index which blocks the creation. + +Index configuration settings can be specified using the `OPTIONS` clause. +However, not all indexes have available configuration settings. +In those cases, nothing needs to be specified and the `OPTIONS` map should be omitted from the query. + +[NOTE] +==== +Creating an index requires link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/database-administration/#access-control-database-administration-index[the `CREATE INDEX` privilege]. +==== + +[NOTE] +==== +An index cannot be used while its `state` is `POPULATING`, which occurs immediately after it is created. +To check the `state` of an index -- whether it is `ONLINE` (usable) or `POPULATING` (still being built; the `populationPercent` column shows the progress of the index creation) -- run the following command: `SHOW INDEXES`. +==== + +[[create-range-index]] +== Create a range index + +Creating a range index can be done with the `CREATE INDEX` command. +Note that the index name must be unique. + +Range indexes have no supported index configuration. + +[[range-indexes-supported-predicates]] +=== Supported predicates + +Range indexes support most types of predicates: + +[cols="2", options="header"] +|=== + +| Predicate | Syntax + +| Equality check. +a| +[source, syntax, role="noheader"] +---- +n.prop = value +---- + +| List membership check. +a| +[source, syntax, role="noheader"] +---- +n.prop IN list +---- + +| Existence check. +a| +[source, syntax, role="noheader"] +---- +n.prop IS NOT NULL +---- + +| Range search. +a| +[source, syntax, role="noheader"] +---- +n.prop > value +---- + +| Prefix search. +a| +[source, syntax, role="noheader"] +---- +STARTS WITH +---- + +|=== + +[[range-indexes-examples]] +=== Examples + +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-single-property-range-index-for-nodes[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-single-property-range-index-for-relationships[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-composite-range-index-for-nodes[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-composite-range-index-for-relationships[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-range-index-by-param[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-range-index-only-if-it-does-not-already-exist[] + +[discrete] +[[create-a-single-property-range-index-for-nodes]] +==== Create a single-property range index for nodes + +The following statement creates a named range index on all nodes labeled with `Person` and which have the `surname` property. + +.Creating a node range index on a single property +[source, cypher] +---- +CREATE INDEX node_range_index_name FOR (n:Person) ON (n.surname) +---- + +[discrete] +[[create-a-single-property-range-index-for-relationships]] +==== Create a single-property range index for relationships + +The following statement creates a named range index on all relationships with relationship type `KNOWS` and property `since`. + +.Creating a relationship range index on a single property +[source, cypher] +---- +CREATE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since) +---- + +[discrete] +[[create-a-composite-range-index-for-nodes]] +==== Create a composite range index for nodes + +A range index on multiple properties is also called a composite index. +For node range indexes, only nodes with the specified label and that contain all the specified properties are added to the index. + +The following statement creates a named composite range index on all nodes labeled with `Person` and which have both an `age` and `country` property. + +.Creating a composite node range index on multiple properties +[source, cypher] +---- +CREATE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country) +---- + +[discrete] +[[create-a-composite-range-index-for-relationships]] +==== Create a composite range index for relationships + +A range index on multiple properties is also called a composite index. +For relationship range indexes, only relationships with the specified type and that contain all the specified properties are added to the index. + +The following statement creates a named composite range index on all relationships labeled with `PURCHASED` and which have both a `date` and `amount` property. + +.Creating a composite relationship range index on multiple properties +[source, cypher] +---- +CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount) +---- + +[discrete] +[[create-a-range-index-by-param]] +==== Create a range index using a parameter + +The following statement creates a named range index on all nodes with a `Person` label and a `firstname` property using a parameter for the index name. + +.Parameters +[source, parameters] +---- +{ + "name": "range_index_param" +} +---- + +.Creating a node range index on a single property +[source, cypher] +---- +CREATE INDEX $name FOR (n:Person) ON (n.firstname) +---- + +[discrete] +[[create-a-range-index-only-if-it-does-not-already-exist]] +==== 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. + +.Creating a range index with `IF NOT EXISTS` +[source, cypher] +---- +CREATE INDEX node_range_index_name IF NOT EXISTS +FOR (n:Person) ON (n.surname) +---- + +The index is not created if there already exists an index with the same schema and type, same name or both. +Instead an informational notification is returned. + +.Notification +[source] +---- +`CREATE RANGE INDEX node_range_index_name IF NOT EXISTS FOR (e:Person) ON (e.surname)` has no effect. +`RANGE INDEX node_range_index_name FOR (e:Person) ON (e.surname)` already exists. +---- + + +[[create-text-index]] +== Create a text index + +Creating a text index can be done with the `CREATE TEXT INDEX` command. +Note that the index name must be unique. + +Text indexes have no supported index configuration. + +See xref:indexes/search-performance-indexes/create-indexes.adoc#text-indexes-trigram-indexes[Trigram indexing] for information about how text indexes process `STRING` values. + + +[[text-indexes-supported-predicates]] +=== Supported predicates + +Text indexes only solve predicates operating on `STRING` values. + +The following predicates that only operate on `STRING` values are always solvable by a text index: + +* `STARTS WITH` +* `ENDS WITH` +* `CONTAINS` + +However, other predicates are only used when it is known that the property is compared to a `STRING`: + +* `n.prop = "string"` +* `n.prop IN ["a", "b", "c"]` + +This means that a text index is not able to solve, for example, e.g. `a.prop = b.prop`, unless a xref:constraints/managing-constraints.adoc#create-property-type-constraints[property type constraint] also exists on the property. + +Text indexes support the following predicates: + +[cols="2", options="header"] +|=== +| Predicate | Syntax + +| Equality check. +a| +[source, syntax, role="noheader"] +---- +n.prop = 'example_string' +---- + +| List membership check. +a| +[source, syntax, role="noheader"] +---- +n.prop IN ['abc', 'example_string', 'neo4j'] +---- + +| Prefix search. +a| +[source, syntax, role="noheader"] +---- +STARTS WITH +---- + +| Suffix search. +a| +[source, syntax, role="noheader"] +---- +ENDS WITH +---- + +| Substring search. +a| +[source, syntax, role="noheader"] +---- +CONTAINS +---- + +|=== + +The above set of predicates can be extended with the use of type constraints. +See the section about xref:indexes/search-performance-indexes/using-indexes.adoc#type-constraints[index compatibility and type constraints] for more information. + +[TIP] +Text indexes are only used for exact query matches. To perform approximate matches (including, for example, variations and typos), and to compute a similarity score between `STRING` values, use semantic xref:indexes/semantic-indexes/full-text-indexes.adoc[full-text indexes] instead. + +[[text-indexes-trigram-indexes]] +=== Trigram indexing + +Text indexes uses trigram indexing. +This means that `STRING` values are indexed into overlapping trigrams, each containing three Unicode code points. +For example, the word `"developer"` would be indexed by the following trigrams: `["dev", "eve", "vel", "elo", "lop", "ope", "per"]`. + +This makes text indexes particularly suitable for substring (`CONTAINS`) and suffix (`ENDS WITH`) searches, as well as prefix searches (`STARTS WITH`). +For example, searches like `CONTAINS "vel"` or `ENDS WITH "per"` can be efficiently performed by directly looking up the relevant trigrams in the index. +By comparison, range indexes, which indexes `STRING` values lexicographically (see xref:indexes/search-performance-indexes/using-indexes.adoc#range-index-backed-order-by[Range index-backed `ORDER BY`] for more information) and are therefore more suited for prefix searches, would need to scan through all indexed values to check if `"vel"` existed anywhere within the text. +For more information, see xref:indexes/search-performance-indexes/using-indexes.adoc#text-indexes[The impact of indexes on query performance -> Text indexes]. + + +[[text-indexes-examples]] +=== Examples + +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-node-text-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-relationship-text-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-text-index-by-param[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-text-index-only-if-it-does-not-already-exist[] + +[discrete] +[[create-a-node-text-index]] +==== Create a node text index + +The following statement creates a named text index on all nodes labeled with `Person` and which have the `nickname` `STRING` property. + +.Creating a node text index on a single property +[source, cypher] +---- +CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname) +---- + +[discrete] +[[create-a-relationship-text-index]] +==== Create a relationship text index + +The following statement creates a named text index on all relationships with relationship type `KNOWS` and `STRING` property `interest`. + +.Creating a relationship text index on a single property +[source, cypher] +---- +CREATE TEXT INDEX rel_text_index_name FOR ()-[r:KNOWS]-() ON (r.interest) +---- + +[discrete] +[[create-a-text-index-by-param]] +==== Create a text index using a parameter + +The following statement creates a named text index on all nodes with the `Person` label the `favoriteColor` `STRING` property using a parameter for the index name. + +.Parameters +[source, parameters] +---- +{ + "name": "text_index_param" +} +---- + +.Creating a node text index on a single property +[source, cypher] +---- +CREATE TEXT INDEX $name FOR (n:Person) ON (n.favoriteColor) +---- + +[discrete] +[[create-a-text-index-only-if-it-does-not-already-exist]] +==== 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. + +The following statement attempts to create a named text index on all nodes labeled with `Person` and which have the `nickname` `STRING` property. + +.Creating a text index with `IF NOT EXISTS` +[source, cypher] +---- +CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname) +---- + +Note that the index is not created if there already exists an index with the same schema and type, same name or both. +Instead, an informational notification is returned. + +.Notification +[source] +---- +`CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (e:Person) ON (e.nickname)` has no effect. +`TEXT INDEX node_text_index_nickname FOR (e:Person) ON (e.nickname)` already exists. +---- + +[[create-point-index]] +== Create a point index + +Creating a point index can be done with the `CREATE POINT INDEX` command. +Note that the index name must be unique. + +Point indexes have supported index configuration. + + +[[point-indexes-supported-predicates]] +=== Supported predicates + +Point indexes only solve predicates operating on `POINT` values. + +Point indexes support the following predicates: + +[cols="2", options="header"] +|=== +| Predicate | Syntax + +| Property point value. +a| +[source, syntax, role="noheader"] +---- +n.prop = point({x: value, y: value}) +---- + +| Within bounding box. +a| +[source, syntax, role="noheader"] +---- +point.withinBBox(n.prop, lowerLeftCorner, upperRightCorner) +---- + +| Distance. +a| +[source, syntax, role="noheader"] +---- +point.distance(n.prop, center) < = distance +---- + +|=== + +The above set of predicates can be extended with the use of type constraints. +See xref:indexes/search-performance-indexes/using-indexes.adoc#type-constraints[The impact of indexes on query performances -> Property type constraints] for more information. + +[TIP] +To learn more about the spatial data types supported by Cypher, see the page about xref:values-and-types/spatial.adoc[Spatial values]. + + +[[point-indexes-examples]] +=== Examples + +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-node-point-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-relationship-point-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-point-index-by-param[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-point-index-only-if-it-does-not-already-exist[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-point-index-specifying-the-index-configuration[] + +[discrete] +[[create-a-node-point-index]] +==== Create a node point index + +The following statement creates a named point index on all nodes labeled with `Person` and which have the `sublocation` `POINT` property. + +.Creating a node point index on a single property +[source, cypher] +---- +CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation) +---- + +[discrete] +[[create-a-relationship-point-index]] +==== Create a relationship point index + +The following statement creates a named point index on all relationships with relationship type `STREET` and `POINT` property `intersection`. + +.Creating a relationship point index on a single property +[source, cypher] +---- +CREATE POINT INDEX rel_point_index_name FOR ()-[r:STREET]-() ON (r.intersection) +---- + +[discrete] +[[create-a-point-index-by-param]] +==== Create a point index using a parameter + +The following statement creates a named point index on all relationships with relationship type `STREET` and `POINT` property `coordinate` using a parameter for the index name. + +.Parameters +[source, parameters] +---- +{ + "name": "point_index_param" +} +---- + +.Creating a relationship point index on a single property +[source, cypher] +---- +CREATE POINT INDEX $name FOR ()-[r:STREET]-() ON (r.coordinate) +---- + +[discrete] +[[create-a-point-index-only-if-it-does-not-already-exist]] +==== 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. + +.Creating a point index with `IF NOT EXISTS` +[source, cypher] +---- +CREATE POINT INDEX node_point_index IF NOT EXISTS +FOR (n:Person) ON (n.sublocation) +---- + +Note that the index is not created if there already exists an index with the same schema and type, same name or both. +Instead, an informational notification is returned. + +.Notification +[source] +---- +`CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (e:Person) ON (e.sublocation)` has no effect. +`POINT INDEX node_point_index_name FOR (e:Person) ON (e.sublocation)` already exists. +---- + +[discrete] +[[create-a-point-index-specifying-the-index-configuration]] +==== Create a point index specifying the index configuration + +To create a point index with a specific index configuration, the `indexConfig` settings in the `OPTIONS` clause. +The valid configuration settings are: + +* `spatial.cartesian.min` (default value: [`-1000000.0`, `-1000000.0`]) +* `spatial.cartesian.max` (default value: [`1000000.0`, `1000000.0`]) +* `spatial.cartesian-3d.min` (default value: [`-1000000.0`, `-1000000.0`, `-1000000.0`]) +* `spatial.cartesian-3d.max` (default value: [`1000000.0`, `1000000.0`, `1000000.0``]) +* `spatial.wgs-84.min` (default value: [`-180.0`, `-90.0`]) +* `spatial.wgs-84.max` (default value: [`-180.0`, `-90.0`]) +* `spatial.wgs-84-3d.min` (default value: [`-180.0`, `-90.0`, `-1000000.0`]) +* `spatial.wgs-84-3d.max` (default value: [`180.0`, `90.0`, `1000000.0`]) + + +The following statement creates a point index specifying the `spatial.cartesian.min` and `spatial.cartesian.max` settings. + +.Creating a point index with index configuration +[source, cypher] +---- +CREATE POINT INDEX point_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] + } +} +---- + +Note that the wgs-84 and 3D cartesian settings, which are not specified in this example, are set with their respective default values. + +[[create-lookup-index]] +== Create a token lookup index + +Two token lookup indexes are created by default when creating a Neo4j database (one node label lookup index and one relationship type lookup index). +Only one node label and one relationship type lookup index can exist at the same time. + +If a token lookup index has been dropped, it can be recreated with the `CREATE LOOKUP INDEX` command. +Note that the index name must be unique. + +Token lookup indexes have no supported index configuration. + + +[[lookup-index-supported-predicates]] +=== Supported predicates + +Token lookup indexes are present by default and solve only node label and relationship type predicates: + +[cols="2, 2a", options="header"] +|=== +| Predicate | Syntax (example) + +| Node label predicate. +| +[source, syntax, role="noheader"] +---- +MATCH (n:Label) +---- + +[source, syntax, role="noheader"] +---- +MATCH (n) +WHERE n:Label +---- + +| Relationship type predicate. +| +[source, syntax, role="noheader"] +---- +MATCH ()-[r:REL]->() +---- + +[source, syntax, role="noheader"] +---- +MATCH ()-[r]->() +WHERE r:REL +---- + +|=== + +[WARNING] +==== +Token lookup indexes improve the performance of Cypher queries and the population of other indexes. Dropping these indexes may lead to severe performance degradation. +==== + + +[[lookup-index-examples]] +=== Examples + +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-node-label-lookup-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-relationship-type-lookup-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-lookup-index-only-if-it-does-not-already-exist[] + +[discrete] +[[create-a-node-label-lookup-index]] +==== Create a node label lookup index + +The following statement creates a named node label lookup index on all nodes with one or more labels: + +// Lookup indexes exist by default, recreating them would raise an error +.Creating a node label lookup index +[source, cypher, role=test-skip] +---- +CREATE LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) +---- + +[NOTE] +==== +Only one node label lookup index can exist at a time. +==== + +[discrete] +[[create-a-relationship-type-lookup-index]] +==== Create a relationship type lookup index + +The following statement creates a named relationship type lookup index on all relationships with any relationship type. + +// Lookup indexes exist by default, recreating them would raise an error +.Creating a relationship type lookup index +[source, cypher, role=test-skip] +---- +CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) +---- + +[NOTE] +==== +Only one relationship type lookup index can exist at a time. +==== + +[discrete] +[[create-a-lookup-index-only-if-it-does-not-already-exist]] +==== Create a token lookup 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. + +.Creating a node label lookup index with `IF NOT EXISTS` +[source, cypher] +---- +CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) +---- + +The index is not created if there already exists an index with the same schema and type, same name or both. +Instead, an informational notification is returned. + +.Notification +[source] +---- +`CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (e) ON EACH labels(e)` has no effect. +`LOOKUP INDEX node_label_lookup_index FOR (e) ON EACH labels(e)` already exists. +---- + +[[create-conflicting-index]] +== Creating an index when a conflicting index or constraint exists + +* xref:indexes/search-performance-indexes/create-indexes.adoc#failure-to-create-an-already-existing-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#failure-to-create-an-index-with-the-same-name-as-an-already-existing-index[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#failure-to-create-an-index-when-a-constraint-already-exists[] +* xref:indexes/search-performance-indexes/create-indexes.adoc#failure-to-create-an-index-with-the-same-name-as-an-already-existing-constraint[] + +[discrete] +[[failure-to-create-an-already-existing-index]] +=== 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. + +//// +[source, cypher, role=test-setup] +---- +CREATE INDEX example_index FOR (n:Book) ON (n.title) +---- +//// + +.Creating a duplicate index +[source, cypher, role=test-fail] +---- +CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) +---- + +In this case, the index can not be created because it already exists. + +.Error message +[source, error] +---- +There already exists an index (:Book {title}). +---- + +Using `IF NOT EXISTS` when creating the index would result in no error and would not create a new index. + +[discrete] +[[failure-to-create-an-index-with-the-same-name-as-an-already-existing-index]] +=== 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 the given name already exists. +The index type of the existing index does not matter. + +//// +[source, cypher, role=test-setup] +---- +CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) +---- +//// + +.Creating an index with a duplicated name +[source, cypher, role=test-fail] +---- +CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) +---- + +In this case, the index cannot be created because there already exists an index with the given name. + +.Error message +[source, error] +---- +There already exists an index called 'indexOnBooks'. +---- + +Using `IF NOT EXISTS` when creating the index would result in no error and would not create a new index. + +[discrete] +[[failure-to-create-an-index-when-a-constraint-already-exists]] +=== 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. +This is only relevant for range indexes. + +//// +[source, cypher, role=test-setup] +---- +CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE +---- +//// + +.Creating a range index on same schema as existing index-backed constraint +[source, cypher, role=test-fail] +---- +CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) +---- + +In this case, the index can not be created because an index-backed constraint already exists on that label and property combination. + +.Error message +[source, error] +---- +There is a uniqueness constraint on (:Book {isbn}), so an index is already created that matches this. +---- + +[discrete] +[[failure-to-create-an-index-with-the-same-name-as-an-already-existing-constraint]] +=== 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 the given name already exists. + +//// +[source, cypher, role=test-setup] +---- +CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL +---- +//// + +.Creating an index with same name as an existing constraint +[source, cypher, role=test-fail] +---- +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 the given name. + +.Error message +[source, error] +---- +There already exists a constraint called 'bookRecommendations'. +---- \ No newline at end of file diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc new file mode 100644 index 000000000..7ca752573 --- /dev/null +++ b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc @@ -0,0 +1,137 @@ +:description: This page explains how to drop indexes used for search performance. += Drop indexes + +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 xref:indexes/search-performance-indexes/list-indexes.adoc[`SHOW INDEXES` command], given in the output column `name`. + +//// +The below indexes are created in schema/indexes/create-indexes.adoc +[source, cypher, role=test-setup] +---- +CREATE INDEX node_range_index_name FOR (n:Person) ON (n.surname); +CREATE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since); +CREATE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country); +CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount); +CREATE INDEX range_index_param FOR (n:Person) ON (n.firstname); +CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname); +CREATE TEXT INDEX rel_text_index_name FOR ()-[r:KNOWS]-() ON (r.interest); +CREATE TEXT INDEX text_index_param FOR (n:Person) ON (n.favoriteColor); +CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation); +CREATE POINT INDEX rel_point_index_name FOR ()-[r:STREET]-() ON (r.intersection); +CREATE POINT INDEX point_index_param FOR ()-[r:STREET]-() ON (r.coordinate); +CREATE POINT INDEX point_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] + } +}; +CREATE INDEX example_index FOR (n:Book) ON (n.title); +CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1); +CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE; +CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL; +---- +//// + +[source, syntax, role="noheader"] +---- +DROP INDEX index_name [IF EXISTS] +---- + +The `DROP INDEX` command is optionally idempotent. +This means that its default behavior is to throw an error if an attempt is made to drop the same index twice. +With `IF EXISTS`, no error is thrown and nothing happens should the index not exist. +Instead, an informational notification is returned detailing that the index does not exist. + +[NOTE] +==== +Dropping an index requires link:{neo4j-docs-base-uri}/operations-manual/current/database-administration/authentication-authorization/database-administration/#access-control-database-administration-index[the `DROP INDEX` privilege]. +==== + + +[[drop-indexes-examples]] +== Examples + +* xref:indexes/search-performance-indexes/drop-indexes.adoc#drop-an-index[] +* xref:indexes/search-performance-indexes/drop-indexes.adoc#drop-an-index-by-param[] +* xref:indexes/search-performance-indexes/drop-indexes.adoc#drop-index-backing-constraint[] +* xref:indexes/search-performance-indexes/drop-indexes.adoc#drop-a-non-existing-index[] + + +[[drop-an-index]] +=== Drop an index + +The following statement attempts to drop the index named `example_index`. + +.Dropping an index +[source, cypher] +---- +DROP INDEX example_index +---- + +If an index with that name exists it is removed, if not the command fails. + + +[[drop-an-index-by-param]] +==== Drop an index using a parameter + +The following statement attempts to drop the index named `range_index_param` using a parameter for the index name. + +.Parameters +[source, parameters] +---- +{ + "name": "range_index_param" +} +---- + +.Dropping an index +[source, cypher] +---- +DROP INDEX $name +---- + +If an index with that name exists it is removed, if not the command fails. + + +[[drop-index-backing-constraint]] +=== Failure to drop an index backing a constraint + +It is not possible to drop indexes that back constraints. + +.Dropping an index backing a constraint +[source, cypher,role=test-fail] +---- +DROP INDEX uniqueBookIsbn +---- + +.Error message +[source, error] +---- +Unable to drop index: Index belongs to constraint: `uniqueBookIsbn` +---- + +Dropping the index-backed constraint also removes the backing index. +For more information, see xref:constraints/managing-constraints.adoc#drop-constraint[Drop a constraint by name]. + + +[[drop-a-non-existing-index]] +=== 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`. + +The following statement attempts to drop the index named `missing_index_name`. + +.Dropping an index with `IF EXISTS` +[source, cypher] +---- +DROP INDEX missing_index_name IF EXISTS +---- + +If an index with that name exists it is removed, if not the command does nothing and an informational notification is instead returned. + +.Notification +[source] +---- +`DROP INDEX missing_index_name IF EXISTS` has no effect. `missing_index_name` does not exist. +---- diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc index 0ebf66f91..aa2795086 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc @@ -1,25 +1,26 @@ :description: Overview of the search-performance indexes available in Neo4j. +include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/asciidoc/courses/cypher-indexes-constraints/ad.adoc[] :page-aliases: indexes-for-search-performance.adoc = Search-performance indexes Search-performance indexes enable quicker retrieval of exact matches between an index and the primary data storage. There are four different search-performance indexes available in Neo4j: -* *Range indexes*: Neo4j’s default index. +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[*Range indexes*]: Neo4j’s default index. Supports most types of predicates. -* *Text indexes*: solves predicates operating on `STRING` values. +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-text-index[*Text indexes*]: solves predicates operating on `STRING` values. Optimized for queries filtering with the `STRING` operators `CONTAINS` and `ENDS WITH`. -* *Point indexes*: solves predicates on spatial `POINT` values. +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[*Point indexes*]: solves predicates on spatial `POINT` values. Optimized for queries filtering on distance or within bounding boxes. -* *Token lookup indexes*: only solves node label and relationship type predicates (i.e. they cannot solve any predicates filtering on properties). +* xref:indexes/search-performance-indexes/create-indexes.adoc#create-lookup-index[*Token lookup indexes*]: only solves node label and relationship type predicates (i.e. they cannot solve any predicates filtering on properties). Two token lookup indexes (one for node labels and one for relationship types) are present when a database is created in Neo4j. -To learn more about creating, listing, and deleting these indexes, as well as more details about the predicates supported by each index type, see xref:indexes/search-performance-indexes/managing-indexes.adoc[]. +To learn more about creating, listing, and deleting these indexes, as well as more details about the predicates supported by each index type, see xref:indexes/search-performance-indexes/create-indexes.adoc[], xref:indexes/search-performance-indexes/list-indexes.adoc[] and xref:indexes/search-performance-indexes/drop-indexes.adoc[]. -For information about how indexes impact the performance of Cypher queries, as well as some heuristics for when to use (and not to use) a search-performance index, see xref:indexes/search-performance-indexes/using-indexes.adoc[]. +For information about how search-performance indexes are used in Cypher queries, how they impact their performance, as well as some heuristics for when to use (and not to use) a search-performance index, see xref:indexes/search-performance-indexes/using-indexes.adoc[]. -Search-performance indexes are used automatically, and if several indexes are available, the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] will try to use the index (or indexes) that can most efficiently solve a particular predicate. +Search-performance indexes are used automatically, and if several indexes are available, the xref:planning-and-tuning/execution-plans.adoc[Cypher planner] tries to use the index (or indexes) that can most efficiently solve a particular predicate. It is, however, possible to explicitly force a query to use a particular index with the `USING` keyword. For more information, see xref:indexes/search-performance-indexes/index-hints.adoc[]. diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc similarity index 50% rename from modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc rename to modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc index a70f9a43a..5a5c803c2 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -1,802 +1,52 @@ -:description: This page explains how to manage indexes used for search performance. -include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/asciidoc/courses/cypher-indexes-constraints/ad.adoc[] +:description: This page explains how to list indexes used for search performance. += Show indexes -= Create, show, and drop indexes - -This page describes how to create, list, and drop search-performance indexes. -The following index types are included in this category: - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[Range indexes] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-text-index[Text indexes] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-point-index[Point indexes] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-lookup-index[Token lookup indexes] - -For information about how search-performance indexes are used in Cypher queries, see xref:indexes/search-performance-indexes/using-indexes.adoc[Using search-performance indexes]. - -[[create-indexes]] -== +CREATE INDEX+ - -Creating an index is done with the `CREATE [index_type] INDEX [index_name]` command. -If no index type is specified in the create command a xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[range index] will be created. - -It is recommended to give the index a name when it is created. -If the index is not explicitly named, it gets an auto-generated name. - -[NOTE] -==== -The index name must be unique among both indexes and constraints. -==== - -The `CREATE INDEX` command is optionally idempotent. -This mean that its default behavior is to throw an error if an attempt is made to create the same index twice. -If `IF NOT EXISTS` is appended to the command, 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. -Instead, an informational notification is returned showing the existing index which blocks the creation. - -Index configuration settings can be specified using the `OPTIONS` clause. -However, not all indexes have available configuration settings. -In those cases, nothing needs to be specified and the `OPTIONS` map should be omitted from the query. - -[NOTE] -Creating an index requires link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/database-administration/#access-control-database-administration-index[the `CREATE INDEX` privilege]. - -[NOTE] -An index cannot be used while its `state` is `POPULATING`, which occurs immediately after it is created. -To check the `state` of an index -- whether it is `ONLINE` (usable) or `POPULATING` (still being built; the `populationPercent` column shows the progress of the index creation) -- run the following command: `SHOW INDEXES`. - -[[create-range-index]] -=== Create a range index - -Creating a range index can be done with the `CREATE INDEX` command. -Note that the index name must be unique. - -Range indexes have no supported index configuration. - -[[range-indexes-supported-predicates]] -[discrete] -==== Supported predicates - -Range indexes support most types of predicates: - -[cols="2", options="header"] -|=== - -| Predicate | Syntax - -| Equality check. -a| -[source, syntax, role="noheader"] ----- -n.prop = value ----- - -| List membership check. -a| -[source, syntax, role="noheader"] ----- -n.prop IN list ----- - -| Existence check. -a| -[source, syntax, role="noheader"] ----- -n.prop IS NOT NULL ----- - -| Range search. -a| -[source, syntax, role="noheader"] ----- -n.prop > value ----- - -| Prefix search. -a| -[source, syntax, role="noheader"] ----- -STARTS WITH ----- - -|=== - -[[range-indexes-examples]] -[discrete] -==== Examples - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-single-property-range-index-for-nodes[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-single-property-range-index-for-relationships[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-composite-range-index-for-nodes[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-composite-range-index-for-relationships[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-range-index-by-param[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-range-index-only-if-it-does-not-already-exist[] - -[discrete] -[[create-a-single-property-range-index-for-nodes]] -===== Create a single-property range index for nodes - -The following statement will create a named range index on all nodes labeled with `Person` and which have the `surname` property. - -.Creating a node range index on a single property -[source, cypher] ----- -CREATE INDEX node_range_index_name FOR (n:Person) ON (n.surname) ----- - -[discrete] -[[create-a-single-property-range-index-for-relationships]] -===== Create a single-property range index for relationships - -The following statement will create a named range index on all relationships with relationship type `KNOWS` and property `since`. - -.Creating a relationship range index on a single property -[source, cypher] ----- -CREATE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since) ----- - -[discrete] -[[create-a-composite-range-index-for-nodes]] -===== Create a composite range index for nodes - -A range index on multiple properties is also called a composite index. -For node range indexes, only nodes with the specified label and that contain all the specified properties will be added to the 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. - -.Creating a composite node range index on multiple properties -[source, cypher] ----- -CREATE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country) ----- - -[discrete] -[[create-a-composite-range-index-for-relationships]] -===== Create a composite range index for relationships - -A range index on multiple properties is also called a composite index. -For relationship range indexes, only relationships with the specified type and that contain all the specified properties will be added to the 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. - -.Creating a composite relationship range index on multiple properties -[source, cypher] ----- -CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount) ----- - -[discrete] -[[create-a-range-index-by-param]] -===== Create a range index using a parameter - -The following statement will create a named range index on all nodes with a `Person` label and a `firstname` property using a parameter for the index name. - -.Parameters -[source, parameters] ----- -{ - "name": "range_index_param" -} ----- - -.Creating a node range index on a single property -[source, cypher] ----- -CREATE INDEX $name FOR (n:Person) ON (n.firstname) ----- - -[discrete] -[[create-a-range-index-only-if-it-does-not-already-exist]] -===== 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. - -.Creating a range index with `IF NOT EXISTS` -[source, cypher] ----- -CREATE INDEX node_range_index_name IF NOT EXISTS -FOR (n:Person) ON (n.surname) ----- - -The index will not be created if there already exists an index with the same schema and type, same name or both. -Instad an informational notification is returned. - -.Notification -[source] ----- -`CREATE RANGE INDEX node_range_index_name IF NOT EXISTS FOR (e:Person) ON (e.surname)` has no effect. -`RANGE INDEX node_range_index_name FOR (e:Person) ON (e.surname)` already exists. ----- - -[[create-text-index]] -=== Create a text index - -Creating a text index can be done with the `CREATE TEXT INDEX` command. -Note that the index name must be unique. - -Text indexes have no supported index configuration. - -See xref:indexes/search-performance-indexes/managing-indexes.adoc#text-indexes-trigram-indexes[Trigram indexing] for information about how text indexes process `STRING` values. - -[[text-indexes-supported-predicates]] -[discrete] -==== Supported predicates - -Text indexes only solve predicates operating on `STRING` values. - -The following predicates that only operate on `STRING` values are always solvable by a text index: - -* `STARTS WITH` -* `ENDS WITH` -* `CONTAINS` - -However, other predicates are only used when it is known that the property is compared to a `STRING`: - -* `n.prop = "string"` -* `n.prop IN ["a", "b", "c"]` - -This means that a text index is not able to solve, for example, e.g. `a.prop = b.prop`, unless a xref:constraints/managing-constraints.adoc#create-property-type-constraints[property type constraint] also exists on the property. - -Text indexes support the following predicates: - -[cols="2", options="header"] -|=== -| Predicate | Syntax - -| Equality check. -a| -[source, syntax, role="noheader"] ----- -n.prop = 'example_string' ----- - -| List membership check. -a| -[source, syntax, role="noheader"] ----- -n.prop IN ['abc', 'example_string', 'neo4j'] ----- - -| Prefix search. -a| -[source, syntax, role="noheader"] ----- -STARTS WITH ----- - -| Suffix search. -a| -[source, syntax, role="noheader"] ----- -ENDS WITH ----- - -| Substring search. -a| -[source, syntax, role="noheader"] ----- -CONTAINS ----- - -|=== - -The above set of predicates can be extended with the use of type constraints. -See the section about xref:indexes/search-performance-indexes/using-indexes.adoc#type-constraints[index compatibility and type constraints] for more information. - -[TIP] -Text indexes are only used for exact query matches. To perform approximate matches (including, for example, variations and typos), and to compute a similarity score between `STRING` values, use semantic xref:indexes/semantic-indexes/full-text-indexes.adoc[full-text indexes] instead. - -[[text-indexes-trigram-indexes]] -==== Trigram indexing - -Text indexes uses trigram indexing. -This means that `STRING` values are indexed into overlapping trigrams, each containing three Unicode code points. -For example, the word `"developer"` would be indexed by the following trigrams: `["dev", "eve", "vel", "elo", "lop", "ope", "per"]`. - -This makes text indexes particularly suitable for substring (`CONTAINS`) and suffix (`ENDS WITH`) searches, as well as prefix searches (`STARTS WITH`). -For example, searches like `CONTAINS "vel"` or `ENDS WITH "per"` can be efficiently performed by directly looking up the relevant trigrams in the index. -By comparison, range indexes, which indexes `STRING` values lexicographically (see xref:indexes/search-performance-indexes/using-indexes.adoc#range-index-backed-order-by[Range index-backed `ORDER BY`] for more information) and are therefore more suited for prefix searches, would need to scan through all indexed values to check if `"vel"` existed anywhere within the text. -For more information, see xref:indexes/search-performance-indexes/using-indexes.adoc#text-indexes[The impact of indexes on query performance -> Text indexes]. - -[discrete] -[[text-indexes-examples]] -==== Examples - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-node-text-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-relationship-text-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-text-index-by-param[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-text-index-only-if-it-does-not-already-exist[] - -[discrete] -[[create-a-node-text-index]] -===== Create a node text index - -The following statement will create a named text index on all nodes labeled with `Person` and which have the `nickname` `STRING` property. - -.Creating a node text index on a single property -[source, cypher] ----- -CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname) ----- - -[discrete] -[[create-a-relationship-text-index]] -===== Create a relationship text index - -The following statement will create a named text index on all relationships with relationship type `KNOWS` and `STRING` property `interest`. - -.Creating a relationship text index on a single property -[source, cypher] ----- -CREATE TEXT INDEX rel_text_index_name FOR ()-[r:KNOWS]-() ON (r.interest) ----- - -[discrete] -[[create-a-text-index-by-param]] -===== Create a text index using a parameter - -The following statement will create a named text index on all nodes with the `Person` label the `favoriteColor` `STRING` property using a parameter for the index name. - -.Parameters -[source, parameters] ----- -{ - "name": "text_index_param" -} ----- - -.Creating a node text index on a single property -[source, cypher] ----- -CREATE TEXT INDEX $name FOR (n:Person) ON (n.favoriteColor) ----- - -[discrete] -[[create-a-text-index-only-if-it-does-not-already-exist]] -===== 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. - -The following statement will attempt to create a named text index on all nodes labeled with `Person` and which have the `nickname` `STRING` property. - -.Creating a text index with `IF NOT EXISTS` -[source, cypher] ----- -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. -Instead, an informational notification is returned. - -.Notification -[source] ----- -`CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (e:Person) ON (e.nickname)` has no effect. -`TEXT INDEX node_text_index_nickname FOR (e:Person) ON (e.nickname)` already exists. ----- - -[[create-point-index]] -=== Create a point index - -Creating a point index can be done with the `CREATE POINT INDEX` command. -Note that the index name must be unique. - -Point indexes have supported index configuration. - -[discrete] -[[point-indexes-supported-predicates]] -==== Supported predicates - -Point indexes only solve predicates operating on `POINT` values. - -Point indexes support the following predicates: - -[cols="2", options="header"] -|=== -| Predicate | Syntax - -| Property point value. -a| -[source, syntax, role="noheader"] ----- -n.prop = point({x: value, y: value}) ----- - -| Within bounding box. -a| -[source, syntax, role="noheader"] ----- -point.withinBBox(n.prop, lowerLeftCorner, upperRightCorner) ----- - -| Distance. -a| -[source, syntax, role="noheader"] ----- -point.distance(n.prop, center) < = distance ----- - -|=== - -The above set of predicates can be extended with the use of type constraints. -See xref:indexes/search-performance-indexes/using-indexes.adoc#type-constraints[The impact of indexes on query performances -> Property type constraints] for more information. - -[TIP] -To learn more about the spatial data types supported by Cypher, see the page about xref:values-and-types/spatial.adoc[Spatial values]. - -[discrete] -[[point-indexes-examples]] -==== Examples - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-node-point-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-relationship-point-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-point-index-by-param[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-point-index-only-if-it-does-not-already-exist[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-point-index-specifying-the-index-configuration[] - -[discrete] -[[create-a-node-point-index]] -===== Create a node point index - -The following statement will create a named point index on all nodes labeled with `Person` and which have the `sublocation` `POINT` property. - -.Creating a node point index on a single property -[source, cypher] ----- -CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation) ----- - -[discrete] -[[create-a-relationship-point-index]] -===== Create a relationship point index - -The following statement will create a named point index on all relationships with relationship type `STREET` and `POINT` property `intersection`. - -.Creating a relationship point index on a single property -[source, cypher] ----- -CREATE POINT INDEX rel_point_index_name FOR ()-[r:STREET]-() ON (r.intersection) ----- - -[discrete] -[[create-a-point-index-by-param]] -===== Create a point index using a parameter - -The following statement will create a named point index on all relationships with relationship type `STREET` and `POINT` property `coordinate` using a parameter for the index name. - -.Parameters -[source, parameters] ----- -{ - "name": "point_index_param" -} ----- - -.Creating a relationship point index on a single property -[source, cypher] ----- -CREATE POINT INDEX $name FOR ()-[r:STREET]-() ON (r.coordinate) ----- - -[discrete] -[[create-a-point-index-only-if-it-does-not-already-exist]] -===== 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. - -.Creating a point index with `IF NOT EXISTS` -[source, cypher] ----- -CREATE POINT INDEX node_point_index IF NOT EXISTS -FOR (n:Person) ON (n.sublocation) ----- - -Note that the index will not be created if there already exists an index with the same schema and type, same name or both. -Instead, an informational notification is returned. - -.Notification -[source] ----- -`CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (e:Person) ON (e.sublocation)` has no effect. -`POINT INDEX node_point_index_name FOR (e:Person) ON (e.sublocation)` already exists. ----- - -[discrete] -[[create-a-point-index-specifying-the-index-configuration]] -===== Create a point index specifying the index configuration - -To create a point index with a specific index configuration, the `indexConfig` settings in the `OPTIONS` clause. -The valid configuration settings are: - -* `spatial.cartesian.min` (default value: [`-1000000.0`, `-1000000.0`]) -* `spatial.cartesian.max` (default value: [`1000000.0`, `1000000.0`]) -* `spatial.cartesian-3d.min` (default value: [`-1000000.0`, `-1000000.0`, `-1000000.0`]) -* `spatial.cartesian-3d.max` (default value: [`1000000.0`, `1000000.0`, `1000000.0``]) -* `spatial.wgs-84.min` (default value: [`-180.0`, `-90.0`]) -* `spatial.wgs-84.max` (default value: [`-180.0`, `-90.0`]) -* `spatial.wgs-84-3d.min` (default value: [`-180.0`, `-90.0`, `-1000000.0`]) -* `spatial.wgs-84-3d.max` (default value: [`180.0`, `90.0`, `1000000.0`]) - - -The following statement will create a point index specifying the `spatial.cartesian.min` and `spatial.cartesian.max` settings. - -.Creating a point index with index configuration -[source, cypher] +//// +The below indexes are created in schema/indexes/create-indexes.adoc +[source, cypher, role=test-setup] ---- -CREATE POINT INDEX point_index_with_config -FOR (n:Label) ON (n.prop2) -OPTIONS { +CREATE INDEX node_range_index_name FOR (n:Person) ON (n.surname); +CREATE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since); +CREATE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country); +CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, r.amount); +CREATE INDEX range_index_param FOR (n:Person) ON (n.firstname); +CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname); +CREATE TEXT INDEX rel_text_index_name FOR ()-[r:KNOWS]-() ON (r.interest); +CREATE TEXT INDEX text_index_param FOR (n:Person) ON (n.favoriteColor); +CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation); +CREATE POINT INDEX rel_point_index_name FOR ()-[r:STREET]-() ON (r.intersection); +CREATE POINT INDEX point_index_param FOR ()-[r:STREET]-() ON (r.coordinate); +CREATE POINT INDEX point_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] } -} ----- - -Note that the wgs-84 and 3D cartesian settings, which are not specified in this example, will be set with their respective default values. - -[[create-lookup-index]] -=== Create a token lookup index - -Two token lookup indexes are created by default when creating a Neo4j database (one node label lookup index and one relationship type lookup index). -Only one node label and one relationship type lookup index can exist at the same time. - -If a token lookup index has been dropped, it can be recreated with the `CREATE LOOKUP INDEX` command. -Note that the index name must be unique. - -Token lookup indexes have no supported index configuration. - -[discrete] -[[lookup-index-supported-predicates]] -==== Supported predicates - -Token lookup indexes are present by default and solve only node label and relationship type predicates: - -[cols="2, 2a", options="header"] -|=== -| Predicate | Syntax (example) - -| Node label predicate. -| -[source, syntax, role="noheader"] ----- -MATCH (n:Label) ----- - -[source, syntax, role="noheader"] ----- -MATCH (n) -WHERE n:Label ----- - -| Relationship type predicate. -| -[source, syntax, role="noheader"] ----- -MATCH ()-[r:REL]->() ----- - -[source, syntax, role="noheader"] ----- -MATCH ()-[r]->() -WHERE r:REL ----- - -|=== - -[WARNING] -==== -Token lookup indexes improve the performance of Cypher queries and the population of other indexes. Dropping these indexes may lead to severe performance degradation. -==== - -[discrete] -[[lookup-index-examples]] -==== Examples - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-node-label-lookup-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-relationship-type-lookup-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-lookup-index-only-if-it-does-not-already-exist[] - -[discrete] -[[create-a-node-label-lookup-index]] -===== Create a node label lookup index - -The following statement will create a named node label lookup index on all nodes with one or more labels: - -// Lookup indexes exist by default, recreating them would raise an error -.Creating a node label lookup index -[source, cypher, role=test-skip] ----- -CREATE LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) ----- - -[NOTE] -==== -Only one node label lookup index can exist at a time. -==== - -[discrete] -[[create-a-relationship-type-lookup-index]] -===== Create a relationship type lookup index - -The following statement will create a named relationship type lookup index on all relationships with any relationship type. - -// Lookup indexes exist by default, recreating them would raise an error -.Creating a relationship type lookup index -[source, cypher, role=test-skip] ----- -CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) ----- - -[NOTE] -==== -Only one relationship type lookup index can exist at a time. -==== - -[discrete] -[[create-a-lookup-index-only-if-it-does-not-already-exist]] -===== Create a token lookup 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. - -.Creating a node label lookup index with `IF NOT EXISTS` -[source, cypher] ----- -CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) ----- - -The index will not be created if there already exists an index with the same schema and type, same name or both. -Instead, an informational notification is returned. - -.Notification -[source] ----- -`CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (e) ON EACH labels(e)` has no effect. -`LOOKUP INDEX node_label_lookup_index FOR (e) ON EACH labels(e)` already exists. ----- - -[[create-conflicting-index]] -=== Creating an index when a conflicting index or constraint exists - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#failure-to-create-an-already-existing-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#failure-to-create-an-index-with-the-same-name-as-an-already-existing-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#failure-to-create-an-index-when-a-constraint-already-exists[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#failure-to-create-an-index-with-the-same-name-as-an-already-existing-constraint[] - -[discrete] -[[failure-to-create-an-already-existing-index]] -==== 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. - -//// -[source, cypher, role=test-setup] ----- -CREATE INDEX example_index FOR (n:Book) ON (n.title) +}; +CREATE INDEX example_index FOR (n:Book) ON (n.title); +CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1); +CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE; +CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL; ---- //// -.Creating a duplicate index -[source, cypher, role=test-fail] ----- -CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) ----- - -In this case, the index can not be created because it already exists. - -.Error message -[source, error] ----- -There already exists an index (:Book {title}). ----- - -Using `IF NOT EXISTS` when creating the index would result in no error and would not create a new index. - -[discrete] -[[failure-to-create-an-index-with-the-same-name-as-an-already-existing-index]] -==== 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 the given name already exists. -The index type of the existing index does not matter. - -//// -[source, cypher, role=test-setup] ----- -CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) ----- -//// - -.Creating an index with a duplicated name -[source, cypher, role=test-fail] ----- -CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) ----- - -In this case, the index cannot be created because there already exists an index with the given name. - -.Error message -[source, error] ----- -There already exists an index called 'indexOnBooks'. ----- - -Using `IF NOT EXISTS` when creating the index would result in no error and would not create a new index. - -[discrete] -[[failure-to-create-an-index-when-a-constraint-already-exists]] -==== 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. -This is only relevant for range indexes. - -//// -[source, cypher, role=test-setup] ----- -CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE ----- -//// - -.Creating a range index on same schema as existing index-backed constraint -[source, cypher, role=test-fail] ----- -CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) ----- - -In this case, the index can not be created because an index-backed constraint already exists on that label and property combination. - -.Error message -[source, error] ----- -There is a uniqueness constraint on (:Book {isbn}), so an index is already created that matches this. ----- - -[discrete] -[[failure-to-create-an-index-with-the-same-name-as-an-already-existing-constraint]] -==== 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 the given name already exists. - -//// -[source, cypher, role=test-setup] ----- -CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL ----- -//// - -.Creating an index with same name as an existing constraint -[source, cypher, role=test-fail] ----- -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 the given name. - -.Error message -[source, error] ----- -There already exists a constraint called 'bookRecommendations'. ----- - - -[[list-indexes]] -== +SHOW INDEXES+ - Listing indexes can be done with `SHOW INDEXES`. [NOTE] +==== Listing indexes requires link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/database-administration/#access-control-database-administration-index[the `SHOW INDEX` privilege]. +==== + -[discrete] [[listing-indexes-examples]] -=== Examples +== Examples + +* xref:indexes/search-performance-indexes/list-indexes.adoc#listing-all-indexes[] +* xref:indexes/search-performance-indexes/list-indexes.adoc#listing-specific-columns[] +* xref:indexes/search-performance-indexes/list-indexes.adoc#listing-indexes-with-filtering[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#listing-all-indexes[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#listing-specific-columns[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#listing-indexes-with-filtering[] -[discrete] [[listing-all-indexes]] -==== Listing all indexes +=== 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 *`. @@ -840,11 +90,11 @@ 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 xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-an-index[`DROP INDEX` command]. +This can be used to drop the index with the xref:indexes/search-performance-indexes/drop-indexes.adoc[`DROP INDEX` command]. + -[discrete] [[listing-specific-columns]] -==== Listing specific columns +=== Listing specific columns It is possible to return only specific columns of the available indexes using the `YIELD` clause: @@ -883,9 +133,9 @@ RETURN name, type, provider, options.indexConfig AS config, createStatement Note that `YIELD` is mandatory if the `RETURN` clause is used. `RETURN` is not, however, mandatory when the YIELD clause is used. -[discrete] + [[listing-indexes-with-filtering]] -==== Listing indexes with filtering +=== Listing indexes with filtering The `SHOW INDEX` command can be filtered in various ways. @@ -918,7 +168,7 @@ SHOW RANGE INDEXES WHERE owningConstraint IS NULL 6 rows ---- -This will only return the default output columns. +This returns only the default output columns. To get all columns, use: @@ -928,7 +178,7 @@ SHOW RANGE INDEXES YIELD * WHERE owningConstraint IS NULL ---- [[listing-indexes-result-columns]] -=== Result columns for listing indexes +== Result columns for listing indexes The below table contains the full information about all columns returned by the `SHOW INDEXES YIELD *` command: @@ -997,7 +247,7 @@ label:default-output[] | `options` | Information retrieved from the `OPTIONS` map about the provider and configuration settings for an index. -If neither is specified when creating the index, this column will return the default values. +If neither is specified when creating the index, this column returns the default values. | `MAP` | `failureMessage` @@ -1009,112 +259,3 @@ If neither is specified when creating the index, this column will return the def | `STRING` |=== - - -[[drop-indexes]] -== +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 xref:indexes/search-performance-indexes/managing-indexes.adoc#list-indexes[`SHOW INDEXES` command], given in the output column `name`. - -[source, syntax, role="noheader"] ----- -DROP INDEX index_name [IF EXISTS] ----- - -The `DROP INDEX` command is optionally idempotent. -This means that its default behavior is to throw an error if an attempt is made to drop the same index twice. -With `IF EXISTS`, no error is thrown and nothing happens should the index not exist. -Instead, an informational notification is returned detailing that the index does not exist. - -[NOTE] -Dropping an index requires link:{neo4j-docs-base-uri}/operations-manual/current/database-administration/authentication-authorization/database-administration/#access-control-database-administration-index[the `DROP INDEX` privilege]. - -[discrete] -[[drop-indexes-examples]] -=== Examples - -* xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-an-index[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-an-index-by-param[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-index-backing-constraint[] -* xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-a-non-existing-index[] - -[discrete] -[[drop-an-index]] -==== Drop an index - -The following statement will attempt to drop the index named `example_index`. - -.Dropping an index -[source, cypher] ----- -DROP INDEX example_index ----- - -If an index with that name exists it is removed, if not the command fails. - -[discrete] -[[drop-an-index-by-param]] -==== Drop an index using a parameter - -The following statement will attempt to drop the index named `range_index_param` using a parameter for the index name. - -.Parameters -[source, parameters] ----- -{ - "name": "range_index_param" -} ----- - -.Dropping an index -[source, cypher] ----- -DROP INDEX $name ----- - -If an index with that name exists it is removed, if not the command fails. - -[discrete] -[[drop-index-backing-constraint]] -==== Failure to drop an index backing a constraint - -It is not possible to drop indexes that back constraints. - -.Dropping an index backing a constraint -[source, cypher,role=test-fail] ----- -DROP INDEX uniqueBookIsbn ----- - -.Error message -[source, error] ----- -Unable to drop index: Index belongs to constraint: `uniqueBookIsbn` ----- - -Dropping the index-backed constraint will also remove the backing index. -For more information, see xref:constraints/managing-constraints.adoc#drop-constraint[Drop a constraint by name]. - -[discrete] -[[drop-a-non-existing-index]] -==== 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`. - -The following statement will attempt to drop the index named `missing_index_name`. - -.Dropping an index with `IF EXISTS` -[source, cypher] ----- -DROP INDEX missing_index_name IF EXISTS ----- - -If an index with that name exists it is removed, if not the command does nothing and an informational notification is instead returned. - -.Notification -[source] ----- -`DROP INDEX missing_index_name IF EXISTS` has no effect. `missing_index_name` does not exist. ----- diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc index 14ca99722..92a629da5 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc @@ -85,7 +85,7 @@ In the above example, had a node label lookup index not existed, the `NodeByLabe While useful, token lookup indexes will rarely be sufficient for applications querying databases of a non-trivial size because they cannot solve any property-related predicates. -For more information about the predicates supported by token lookup indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#lookup-index-supported-predicates[Create, show, and delete indexes -> Token lookup indexes: supported predicates]. +For more information about the predicates supported by token lookup indexes, see xref:indexes/search-performance-indexes/create-indexes.adoc#lookup-index-supported-predicates[Create indexes -> Create a token lookup index -> Supported predicates]. [[range-indexes]] == Range indexes @@ -103,7 +103,7 @@ CREATE INDEX range_index_type FOR (n:PointOfInterest) ON (n.type) [NOTE] If no index type is specified when creating an index, Neo4j will default to create a range index. -For more information about creating indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-indexes[Create, show, and delete indexes -> CREATE INDEX]. +For more information about creating indexes, see xref:indexes/search-performance-indexes/create-indexes.adoc[]. .Rerun query after the creation of a relevant index [source,cypher] @@ -139,7 +139,7 @@ This only produces 26 rows (representing the 26 `PointOfInterest` nodes in the d These points all illustrate the fundamental point that search-performance indexes can significantly improve the performance of Cypher queries. -For more information about the predicates supported by range indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#range-indexes-supported-predicates[Create, show, and delete indexes -> Range indexes: supported predicates]. +For more information about the predicates supported by range indexes, see xref:indexes/search-performance-indexes/create-indexes.adoc#range-indexes-supported-predicates[Create indexes -> Create a range index -> Supported predicates]. [[text-indexes]] == Text indexes @@ -232,7 +232,7 @@ Total database accesses: 7, total allocated memory: 312 This is because range indexes store `STRING` values alphabetically. This means that, while they are very efficient for retrieving exact matches of a `STRING`, or for prefix matching, they are less efficient for suffix and contains searches, where they have to scan all relevant properties to filter any matches. -Text indexes do not store `STRING` properties alphabetically, and are instead optimized for suffix and contains searches (for more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#text-indexes-trigram-indexes[Create a text index -> Trigram indexing]). +Text indexes do not store `STRING` properties alphabetically, and are instead optimized for suffix and contains searches (for more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#text-indexes-trigram-indexes[Create a text index -> Trigram indexing]). That said, if no range index had been present on the name property, the previous query would still have been able to utilize the text index. It would have done so less efficiently than a range index, but it still would have been useful. @@ -241,7 +241,7 @@ For more information about range index ordering, see the section on xref:indexes [TIP] Text indexes are only used for exact query matches. To perform approximate matches (including, for example, variations and typos), and to compute a similarity score between `STRING` values, use semantic xref:indexes/semantic-indexes/full-text-indexes.adoc[full-text indexes] instead. -For more information about the predicates supported by text indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#text-indexes-supported-predicates[Create, show, and delete indexes -> Text indexes: supported predicates]. +For more information about the predicates supported by text indexes, see xref:indexes/search-performance-indexes/create-indexes.adoc#text-indexes-supported-predicates[Create indexes -> Create a text index -> Supported predicates]. [[text-index-dictionary-variables]] === Ensuring text index use @@ -339,12 +339,12 @@ RETURN n.name AS name, n.type AS type Total database accesses: 34, total allocated memory: 312 ---- -For more information about the predicates supported by point indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#point-indexes-supported-predicates[Create, show, and delete indexes -> Point indexes: supported predicates]. +For more information about the predicates supported by point indexes, see xref:indexes/search-performance-indexes/create-indexes.adoc#point-indexes-supported-predicates[Create indexes -> Create a point index -> Supported predicates]. [[point-index-config-settings]] === Point index configuration settings -It is possible to xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-point-index-specifying-the-index-configuration[configure point indexes] to only index properties within a specific geographical area. +It is possible to xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-point-index-specifying-the-index-configuration[configure point indexes] to only index properties within a specific geographical area. This is done by specifying either of the following settings in the `indexConfig` part of the `OPTIONS` clause when creating a point index: * `spatial.cartesian.min` and `spatial.cartesian.max`: used for xref:values-and-types/spatial.adoc#spatial-values-crs-cartesian[Cartesian 2D] coordinate systems. @@ -1003,12 +1003,12 @@ As a result of these two points, deciding what to index (and what not to index) Unused indexes take up unnecessary storage space and it may be beneficial to remove them. Knowing which indexes are most frequently used by the queries against a database can, however, be difficult. -There are three relevant columns returned by the xref:indexes/search-performance-indexes/managing-indexes.adoc#list-indexes[`SHOW INDEX`] command which can help identify redundant indexes: +There are three relevant columns returned by the xref:indexes/search-performance-indexes/list-indexes.adoc[`SHOW INDEX`] command which can help identify redundant indexes: * *`lastRead`*: returns the last time the index was used for reading. * *`readCount`*: returns the number of read queries issued to the index. * *`trackedSince`* returns the time when usage statistics tracking started for an index.footnote:[The `trackedSince` column is not part of the default return columns for the `SHOW INDEXES` command. To return this and all other non-default columns, use `SHOW INDEXES YIELD *`. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#listing-indexes-result-columns[Create, show, and delete indexes -> Result columns for listing indexes].] +For more information, see xref:indexes/search-performance-indexes/list-indexes.adoc#listing-indexes-result-columns[Create, show, and delete indexes -> Result columns for listing indexes].] To return these values (along with other relevant information) for the indexes in a database, run the following query: @@ -1018,7 +1018,7 @@ To return these values (along with other relevant information) for the indexes i SHOW INDEX YIELD name, type, entityType, labelsOrTypes, properties, lastRead, readCount, trackedSince ---- -If any unused indexes are identified, it may be beneficial to delete them using the xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-indexes[`DROP INDEX`] command. +If any unused indexes are identified, it may be beneficial to delete them using the xref:indexes/search-performance-indexes/drop-indexes.adoc#drop-indexes[`DROP INDEX`] command. [[summary]] == Summary diff --git a/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc b/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc index 7f3b1dbc6..a4382caef 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc @@ -3,7 +3,7 @@ = Full-text indexes A full-text index is used to index nodes and relationships by `STRING` properties. -Unlike xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[range] and xref:indexes/search-performance-indexes/managing-indexes.adoc#create-text-index[text] indexes, which can only perform limited `STRING` matching (exact, prefix, substring, or suffix matches), full-text indexes stores individual words in any given `STRING` property. +Unlike xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[range] and xref:indexes/search-performance-indexes/create-indexes.adoc#create-text-index[text] indexes, which can only perform limited `STRING` matching (exact, prefix, substring, or suffix matches), full-text indexes stores individual words in any given `STRING` property. This means that full-text indexes can be used to match within the _content_ of a `STRING` property. Full-text indexes also return a score of proximity between a given query string and the `STRING` values stored in the database, thus enabling them to semantically interpret data. @@ -54,10 +54,10 @@ This statement creates a full-text index named `namesAndTeams` on each `name` an CREATE FULLTEXT INDEX namesAndTeams FOR (n:Employee|Manager) ON EACH [n.name, n.team] ---- -This query highlights two key differences between full-text and xref:indexes/search-performance-indexes/managing-indexes.adoc[search-performance indexes]: +This query highlights two key differences between full-text and xref:indexes/search-performance-indexes/index.adoc[]: * Full-text indexes can be applied to more than one node label. -* Full-text indexes can be applied to more than one property, but unlike xref:indexes/search-performance-indexes/managing-indexes.adoc#create-a-composite-range-index-for-nodes[composite search-performance indexes], a full-text index stores entities that have _at least_ one of the indexed labels or relationship types, and _at least_ one of the indexed properties. +* Full-text indexes can be applied to more than one property, but unlike xref:indexes/search-performance-indexes/create-indexes.adoc#create-a-composite-range-index-for-nodes[composite search-performance indexes], a full-text index stores entities that have _at least_ one of the indexed labels or relationship types, and _at least_ one of the indexed properties. Similarly, though a relationship can have only one type, a full-text index can store multiple relationship types. In that case, all types matching _at least one_ of the relationship types and _at least one_ of the indexed properties will be included. @@ -133,7 +133,7 @@ For more information on how to configure full-text indexes, refer to the link:{n [[query-full-text-indexes]] == Query full-text indexes -Unlike xref:indexes/search-performance-indexes/managing-indexes.adoc[search-performance indexes], full-text indexes are not automatically used by the xref:planning-and-tuning/execution-plans.adoc[Cypher query planner]. +Unlike xref:indexes/search-performance-indexes/index.adoc[], full-text indexes are not automatically used by the xref:planning-and-tuning/execution-plans.adoc[Cypher query planner]. To query a full-text index, use either the link:{neo4j-docs-base-uri}/operations-manual/current/procedures/#procedure_db_index_fulltext_queryNodes[`db.index.fulltext.queryNodes()`] or the link:{neo4j-docs-base-uri}/operations-manual/current/procedures/#procedure_db_index_fulltext_queryRelationships[`db.index.fulltext.queryRelationships()`] procedure. [NOTE] @@ -334,13 +334,13 @@ SHOW FULLTEXT INDEXES YIELD * +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ---- -For a full description of all return columns, see xref:indexes/search-performance-indexes/managing-indexes.adoc#listing-indexes-result-columns[Search-performance indexes -> Result columns for listing indexes]. +For a full description of all return columns, see xref:indexes/search-performance-indexes/list-indexes.adoc#listing-indexes-result-columns[Search-performance indexes -> List indexes -> Result columns for listing indexes]. [[drop-full-text-indexes]] == Drop full-text indexes -A full-text node index is dropped by using the xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-an-index[same command as for other indexes], `DROP INDEX`. +A full-text node index is dropped by using the xref:indexes/search-performance-indexes/drop-indexes.adoc[same command as for other indexes], `DROP INDEX`. In the following example, the previously created `communications` full-text index is deleted from the database: diff --git a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc index 5107b6b00..b972fbd1f 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc @@ -261,7 +261,7 @@ For more information about what Java versions are supported by different Neo4j v == Show vector indexes To list all vector indexes in a database, use the `SHOW VECTOR INDEXES` command. -This is the same xref:indexes/search-performance-indexes/managing-indexes.adoc#list-indexes[`SHOW` command as for other indexes], with the index type filtering on `VECTOR`. +This is the same xref:indexes/search-performance-indexes/list-indexes.adoc[`SHOW` command as for other indexes], with the index type filtering on `VECTOR`. [NOTE] Listing indexes requires link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/database-administration/#access-control-database-administration-index[the `SHOW INDEX` privilege]. @@ -286,7 +286,7 @@ SHOW VECTOR INDEXES ---- ==== -For a full description of all return columns, see xref:indexes/search-performance-indexes/managing-indexes#listing-indexes-result-columns[Search-performance indexes → Result columns for listing indexes]. +For a full description of all return columns, see xref:indexes/search-performance-indexes/list-indexes.adoc#listing-indexes-result-columns[Search-performance indexes → Result columns for listing indexes]. .Show vector indexes with full or filtered details ==== @@ -331,7 +331,7 @@ SHOW VECTOR INDEXES YIELD name, type, entityType, labelsOrTypes, properties [[drop-vector-indexes]] == Drop vector indexes -A vector index is dropped by using the xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-an-index[same command as for other indexes], `DROP INDEX`. +A vector index is dropped by using the xref:indexes/search-performance-indexes/drop-indexes.adoc[same command as for other indexes], `DROP INDEX`. The index name can also be given as a parameter when dropping an index: `DROP INDEX $name`. [NOTE] diff --git a/modules/ROOT/pages/indexes/syntax.adoc b/modules/ROOT/pages/indexes/syntax.adoc index 8ca4b2e38..21353a4ec 100644 --- a/modules/ROOT/pages/indexes/syntax.adoc +++ b/modules/ROOT/pages/indexes/syntax.adoc @@ -62,7 +62,7 @@ ON (r.propertyName_1[, r.propertyName_n]) ---- -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[Create, show, and delete indexes -> Create a range index]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[Create indexes -> Create a range index]. [[create-text-index]] === Text indexes @@ -89,7 +89,7 @@ ON (r.propertyName_1) [NOTE] It is not possible to create composite text indexes on multiple properties. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-text-index[Create, show, and delete indexes -> Create a text index]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-text-index[Create indexes -> Create a text index]. [[create-point-index]] === Point indexes @@ -126,7 +126,7 @@ The following settings can be specified for point indexes: [NOTE] It is not possible to create composite point indexes on multiple properties. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-point-index[Create, show, and delete indexes -> Create a point index]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[Create indexes -> Create a point index]. [[create-lookup-index]] === Token lookup indexes @@ -152,7 +152,7 @@ ON [EACH] type(r) Two token lookup indexes are present by default when creating a Neo4j database, and only one node label lookup index and one relationship type lookup index can exist at the same time. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-lookup-index[Create, show, and delete indexes -> Create a token lookup index]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-lookup-index[Create indexes -> Create a token lookup index]. [[create-full-text-index]] === Full-text indexes @@ -239,7 +239,7 @@ SHOW [ALL | FULLTEXT | LOOKUP | POINT | RANGE | TEXT | VECTOR] INDEX[ES] When using the `RETURN` clause, the `YIELD` clause is mandatory. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#list-indexes[Create, show, and delete indexes -> SHOW INDEXES]. +For more information, see xref:indexes/search-performance-indexes/list-indexes.adoc[]. [[query-semantic-indexes]] == Query semantic indexes @@ -312,4 +312,4 @@ Dropping indexes requires link:{neo4j-docs-base-uri}/operations-manual/current/a DROP INDEX index_name [IF EXISTS] ---- -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#drop-indexes[Create, show, and delete indexes -> DROP INDEX]. +For more information, see xref:indexes/search-performance-indexes/drop-indexes.adoc[]. diff --git a/modules/ROOT/pages/values-and-types/spatial.adoc b/modules/ROOT/pages/values-and-types/spatial.adoc index a115d692e..3c9f5d442 100644 --- a/modules/ROOT/pages/values-and-types/spatial.adoc +++ b/modules/ROOT/pages/values-and-types/spatial.adoc @@ -27,7 +27,7 @@ Values with the `POINT` type have the following characteristics: This means it contains either 2 or 3 64-bit `FLOAT` values, which together are called the _Coordinate_. * Each point will also be associated with a specific xref::values-and-types/spatial.adoc#spatial-values-crs[Coordinate Reference System] (CRS) that determines the meaning of the values in the _Coordinate_. * Instances of `POINT` and `LIST` can be assigned to node and relationship properties. -* Nodes and relationships with `POINT` or `LIST` properties can be indexed using a xref:indexes/search-performance-indexes/managing-indexes.adoc#create-point-index[point index]. +* Nodes and relationships with `POINT` or `LIST` properties can be indexed using a xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[point index]. This is true for all CRSs (and for both 2D and 3D). * The xref::functions/spatial.adoc#functions-distance[distance function] will work on points in all CRS and in both 2D and 3D, but only if the two points have the same CRS (and therefore also same dimension). @@ -256,10 +256,10 @@ If there is a range or point index on a particular node or relationship property In a point index, Neo4j uses space filling curves in 2D or 3D over an underlying generalized B+Tree. Point indexes are optimized for distance and bounding box queries. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-point-index[Managing indexes -> Point indexes]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-point-index[Create indexes -> Point indexes]. In a range index, the points will be sorted according to their lexicographic ordering per coordinate reference system. For point values, this index has support for equality checks. -For more information, see xref:indexes/search-performance-indexes/managing-indexes.adoc#create-range-index[Managing indexes -> Range indexes]. +For more information, see xref:indexes/search-performance-indexes/create-indexes.adoc#create-range-index[Create indexes -> Range indexes]. [[spatial-values-comparability-orderability]] == Comparability and orderability