From 60a49bdbf2c164df9f26f1b464410a58730d667b Mon Sep 17 00:00:00 2001 From: Richard Sill Date: Fri, 7 Nov 2025 09:32:36 +0100 Subject: [PATCH 1/6] split a file --- .../create-indexes.adoc | 778 ++++++++++++++++++ ...anaging-indexes.adoc => drop-indexes.adoc} | 0 .../list-indexes.adoc | 247 ++++++ 3 files changed, 1025 insertions(+) create mode 100644 modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc rename modules/ROOT/pages/indexes/search-performance-indexes/{managing-indexes.adoc => drop-indexes.adoc} (100%) create mode 100644 modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc 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..81c984f7c --- /dev/null +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -0,0 +1,778 @@ +: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[] + += 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] +---- +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) +---- +//// + +.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/managing-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc similarity index 100% rename from modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc rename to modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc new file mode 100644 index 000000000..903c86f77 --- /dev/null +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -0,0 +1,247 @@ +: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[] + += 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]. + + +[[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 + +* 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 + +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 *`. + +.Showing all indexes +[source, cypher, role=test-result-skip] +---- +SHOW INDEXES +---- + +// SHOW INDEXES default outputs +// 4.4: id, name, state, populationPercent, uniqueness, type, entityType, labelsOrTypes, properties, indexProvider +// 5.0: id, name, state, populationPercent, type, entityType, labelsOrTypes, properties, indexProvider, owningConstraint +// 5.8: id, name, state, populationPercent, type, entityType, labelsOrTypes, properties, indexProvider, owningConstraint, lastRead, readCount + +.Result +[queryresult] +---- ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint | lastRead | readCount | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 3 | "composite_range_node_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["age", "country"] | "range-1.0" | NULL | NULL | 0 | +| 4 | "composite_range_rel_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["PURCHASED"] | ["date", "amount"] | "range-1.0" | NULL | 2023-03-13T11:41:44.537Z | 1 | +| 16 | "example_index" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["title"] | "range-1.0" | NULL | 2023-04-10T15:41:44.537Z | 2 | +| 17 | "indexOnBooks" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Label1"] | ["prop1"] | "text-2.0" | NULL | NULL | 0 | +| 14 | "node_label_lookup_index" | "ONLINE" | 100.0 | "LOOKUP" | "NODE" | NULL | NULL | "token-lookup-1.0" | NULL | 2023-04-13T08:11:15.537Z | 10 | +| 10 | "node_point_index_name" | "ONLINE" | 100.0 | "POINT" | "NODE" | ["Person"] | ["sublocation"] | "point-1.0" | NULL | 2023-04-05T16:21:44.692Z | 1 | +| 1 | "node_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["surname"] | "range-1.0" | NULL | 2022-12-30T02:01:44.537Z | 6 | +| 6 | "node_text_index_nickname" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Person"] | ["nickname"] | "text-2.0" | NULL | 2023-04-13T11:41:44.537Z | 2 | +| 12 | "point_index_param" | "ONLINE" | 100.0 | "POINT" | "RELATIONSHIP" | ["STREET"] | ["coordinate"] | "point-1.0" | NULL | NULL | 0 | +| 13 | "point_index_with_config" | "ONLINE" | 100.0 | "POINT" | "NODE" | ["Label"] | ["prop2"] | "point-1.0" | NULL | NULL | 0 | +| 5 | "range_index_param" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["firstname"] | "range-1.0" | NULL | 2023-12-13T08:23:53.338Z | 2 | +| 11 | "rel_point_index_name" | "ONLINE" | 100.0 | "POINT" | "RELATIONSHIP" | ["STREET"] | ["intersection"] | "point-1.0" | NULL | 2023-03-03T13:37:42.537Z | 2 | +| 2 | "rel_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["KNOWS"] | ["since"] | "range-1.0" | NULL | 2023-04-12T10:41:44.692Z | 5 | +| 7 | "rel_text_index_name" | "ONLINE" | 100.0 | "TEXT" | "RELATIONSHIP" | ["KNOWS"] | ["interest"] | "text-2.0" | NULL | 2023-04-01T10:40:44.537Z | 3 | +| 15 | "rel_type_lookup_index" | "ONLINE" | 100.0 | "LOOKUP" | "RELATIONSHIP" | NULL | NULL | "token-lookup-1.0" | NULL | 2023-04-12T21:41:44.537Z | 7 | +| 8 | "text_index_param" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Person"] | ["favoriteColor"] | "text-2.0" | NULL | NULL | 0 | +| 18 | "uniqueBookIsbn" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["isbn"] | "range-1.0" | "uniqueBookIsbn" | 2023-04-13T11:41:44.692Z | 6 | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +18 rows +---- + +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]. + +[discrete] +[[listing-specific-columns]] +==== Listing specific columns + +It is possible to return only specific columns of the available indexes using the `YIELD` clause: + + +.Returning specific columns for all indexes +[source, cypher, role=test-result-skip] +---- +SHOW INDEXES +YIELD name, type, indexProvider AS provider, options, createStatement +RETURN name, type, provider, options.indexConfig AS config, createStatement +---- + +.Result +[queryresult] +---- ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| name | type | provider | config | createStatement | ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "composite_range_node_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `composite_range_node_index_name` FOR (n:`Person`) ON (n.`age`, n.`country`)" | +| "composite_range_rel_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `composite_range_rel_index_name` FOR ()-[r:`PURCHASED`]-() ON (r.`date`, r.`amount`)" | +| "example_index" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `example_index` FOR (n:`Book`) ON (n.`title`)" | +| "indexOnBooks" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `indexOnBooks` FOR (n:`Label1`) ON (n.`prop1`)" | +| "index_343aff4e" | "LOOKUP" | "token-lookup-1.0" | {} | "CREATE LOOKUP INDEX `index_343aff4e` FOR (n) ON EACH labels(n)" | +| "index_f7700477" | "LOOKUP" | "token-lookup-1.0" | {} | "CREATE LOOKUP INDEX `index_f7700477` FOR ()-[r]-() ON EACH type(r)" | +| "node_point_index_name" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-1000000.0, -1000000.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [1000000.0, 1000000.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `node_point_index_name` FOR (n:`Person`) ON (n.`sublocation`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | +| "node_range_index" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `node_range_index` FOR (n:`Person`) ON (n.`surname`)" | +| "node_text_index_nickname" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `node_text_index_nickname` FOR (n:`Person`) ON (n.`nickname`)" | +| "point_index_with_config" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-100.0, -100.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [100.0, 100.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `point_index_with_config` FOR (n:`Label`) ON (n.`prop2`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [100.0, 100.0],`spatial.cartesian.min`: [-100.0, -100.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | +| "rel_point_index_name" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-1000000.0, -1000000.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [1000000.0, 1000000.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `rel_point_index_name` FOR ()-[r:`STREET`]-() ON (r.`intersection`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | +| "rel_range_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `rel_range_index_name` FOR ()-[r:`KNOWS`]-() ON (r.`since`)" | +| "rel_text_index_name" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `rel_text_index_name` FOR ()-[r:`KNOWS`]-() ON (r.`interest`)" | +| "uniqueBookIsbn" | "RANGE" | "range-1.0" | {} | "CREATE CONSTRAINT `uniqueBookIsbn` FOR (n:`Book`) REQUIRE (n.`isbn`) IS UNIQUE" | ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---- + +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 + +The `SHOW INDEX` command can be filtered in various ways. + +For example, to show only range indexes, use `SHOW RANGE INDEXES`. + +Another more flexible way of filtering the output is to use the `WHERE` clause. +An example is to only show indexes not belonging to constraints. + +To show only range indexes that does not belong to a constraint we can combine the filtering versions. + +.Showing range indexes +[source, cypher, role=test-result-skip] +---- +SHOW RANGE INDEXES WHERE owningConstraint IS NULL +---- + +.Result +[queryresult] +---- ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint | lastRead | readCount | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 3 | "composite_range_node_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["age", "country"] | "range-1.0" | NULL | NULL | 0 | +| 4 | "composite_range_rel_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["PURCHASED"] | ["date", "amount"] | "range-1.0" | NULL | 2023-03-13T11:41:44.537Z | 1 | +| 16 | "example_index" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["title"] | "range-1.0" | NULL | 2023-04-10T15:41:44.537Z | 2 | +| 1 | "node_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["surname"] | "range-1.0" | NULL | 2022-12-30T02:01:44.537Z | 6 | +| 5 | "range_index_param" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["firstname"] | "range-1.0" | NULL | 2023-12-13T08:23:53.338Z | 2 | +| 2 | "rel_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["KNOWS"] | ["since"] | "range-1.0" | NULL | 2023-04-12T10:41:44.692Z | 5 | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +6 rows +---- + +This will only return the default output columns. + +To get all columns, use: + +[source, syntax, role="noheader"] +---- +SHOW RANGE INDEXES YIELD * WHERE owningConstraint IS NULL +---- + +[[listing-indexes-result-columns]] +=== Result columns for listing indexes + +The below table contains the full information about all columns returned by the `SHOW INDEXES YIELD *` command: + +.List indexes output +[options="header", cols="4,6,2"] +|=== +| Column | Description | Type + +| `id` +| The id of the index. label:default-output[] +| `INTEGER` + +| `name` +| Name of the index (explicitly set by the user or automatically assigned). label:default-output[] +| `STRING` + +| `state` +| Current state of the index. label:default-output[] +| `STRING` + +| `populationPercent` +| % of index population. label:default-output[] +| `FLOAT` + +| `type` +| The IndexType of this index (`FULLTEXT`, `LOOKUP`, `POINT`, `RANGE`, `TEXT`, or `VECTOR`). label:default-output[] +| `STRING` + +| `entityType` +| Type of entities this index represents (`NODE` or `RELATIONSHIP`). label:default-output[] +| `STRING` + +| `labelsOrTypes` +| The labels or relationship types of this index. label:default-output[] +| `LIST` + +| `properties` +| The properties of this index. label:default-output[] +| `LIST` + +| `indexProvider` +| The index provider for this index. label:default-output[] +| `STRING` + + +| `owningConstraint` +| The name of the constraint the index is associated with or `null` if the index is not associated with any constraint. label:default-output[] +| `STRING` + +| `lastRead` +| The last time the index was used for reading. +Returns `null` if the index has not been read since `trackedSince`, or if the statistics are not tracked. +label:default-output[] + +| `ZONED DATETIME` + +| `readCount` +| The number of read queries that have been issued to this index since `trackedSince`, or `null` if the statistics are not tracked. label:default-output[] + +| `INTEGER` + +| `trackedSince` +| The time when usage statistics tracking started for this index, or `null` if the statistics are not tracked. + +| `ZONED DATETIME` + +| `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. +| `MAP` + +| `failureMessage` +| The failure description of a failed index. +| `STRING` + +| `createStatement` +| Statement used to create the index. +| `STRING` + +|=== From 1b91dd1b05140125dd486498d0b36130a16e5f68 Mon Sep 17 00:00:00 2001 From: Richard Sill Date: Tue, 25 Nov 2025 16:43:04 +0100 Subject: [PATCH 2/6] fixed incoming links, divided files properly, updated index --- modules/ROOT/content-nav.adoc | 4 +- .../gql-conformance/additional-cypher.adoc | 8 +- .../tutorials/advanced-query-tuning.adoc | 2 +- .../tutorials/basic-query-tuning.adoc | 2 +- modules/ROOT/pages/clauses/merge.adoc | 2 +- .../constraints/managing-constraints.adoc | 6 +- .../create-indexes.adoc | 154 ++- .../drop-indexes.adoc | 1043 +---------------- .../search-performance-indexes/index.adoc | 12 +- .../list-indexes.adoc | 50 +- .../using-indexes.adoc | 20 +- .../semantic-indexes/full-text-indexes.adoc | 12 +- .../semantic-indexes/vector-indexes.adoc | 6 +- modules/ROOT/pages/indexes/syntax.adoc | 12 +- .../ROOT/pages/values-and-types/spatial.adoc | 6 +- 15 files changed, 160 insertions(+), 1179 deletions(-) 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 index 81c984f7c..51031b9ff 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -1,23 +1,8 @@ -: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[] - -= 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+ +: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/managing-indexes.adoc#create-range-index[range index] will be created. +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. 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. @@ -45,7 +30,7 @@ An index cannot be used while its `state` is `POPULATING`, which occurs immediat 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 +== Create a range index Creating a range index can be done with the `CREATE INDEX` command. Note that the index name must be unique. @@ -53,8 +38,7 @@ Note that the index name must be unique. Range indexes have no supported index configuration. [[range-indexes-supported-predicates]] -[discrete] -==== Supported predicates +=== Supported predicates Range indexes support most types of predicates: @@ -101,19 +85,18 @@ STARTS WITH |=== [[range-indexes-examples]] -[discrete] -==== Examples +=== 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[] +* 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 +==== 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. @@ -125,7 +108,7 @@ 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 +==== 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`. @@ -137,7 +120,7 @@ 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 +==== 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. @@ -152,7 +135,7 @@ 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 +==== 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. @@ -167,7 +150,7 @@ CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, [discrete] [[create-a-range-index-by-param]] -===== Create a range index using a parameter +==== 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. @@ -187,7 +170,7 @@ 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 +==== 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. @@ -208,19 +191,20 @@ Instad an informational notification is returned. `RANGE INDEX node_range_index_name FOR (e:Person) ON (e.surname)` already exists. ---- + [[create-text-index]] -=== Create a 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. +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]] -[discrete] -==== Supported predicates +=== Supported predicates Text indexes only solve predicates operating on `STRING` values. @@ -287,7 +271,7 @@ See the section about xref:indexes/search-performance-indexes/using-indexes.adoc 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 +=== Trigram indexing Text indexes uses trigram indexing. This means that `STRING` values are indexed into overlapping trigrams, each containing three Unicode code points. @@ -298,18 +282,18 @@ For example, searches like `CONTAINS "vel"` or `ENDS WITH "per"` can be efficien 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 +=== 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[] +* 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 +==== 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. @@ -321,7 +305,7 @@ CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname) [discrete] [[create-a-relationship-text-index]] -===== 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`. @@ -333,7 +317,7 @@ 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 +==== 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. @@ -353,7 +337,7 @@ 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 +==== 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. @@ -376,16 +360,16 @@ Instead, an informational notification is returned. ---- [[create-point-index]] -=== Create a 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 +=== Supported predicates Point indexes only solve predicates operating on `POINT` values. @@ -424,19 +408,19 @@ See xref:indexes/search-performance-indexes/using-indexes.adoc#type-constraints[ [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 +=== 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[] +* 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 +==== 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. @@ -448,7 +432,7 @@ CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation) [discrete] [[create-a-relationship-point-index]] -===== 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`. @@ -460,7 +444,7 @@ 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 +==== 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. @@ -480,7 +464,7 @@ 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 +==== 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. @@ -503,7 +487,7 @@ Instead, an informational notification is returned. [discrete] [[create-a-point-index-specifying-the-index-configuration]] -===== 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: @@ -536,7 +520,7 @@ OPTIONS { 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 +== 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. @@ -546,9 +530,9 @@ Note that the index name must be unique. Token lookup indexes have no supported index configuration. -[discrete] + [[lookup-index-supported-predicates]] -==== Supported predicates +=== Supported predicates Token lookup indexes are present by default and solve only node label and relationship type predicates: @@ -589,17 +573,17 @@ WHERE r:REL 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 +=== 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[] +* 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 +==== 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: @@ -617,7 +601,7 @@ Only one node label lookup index can exist at a time. [discrete] [[create-a-relationship-type-lookup-index]] -===== 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. @@ -635,7 +619,7 @@ 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 +==== 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. @@ -656,16 +640,16 @@ Instead, an informational notification is returned. ---- [[create-conflicting-index]] -=== Creating an index when a conflicting index or constraint exists +== 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[] +* 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 +=== 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. @@ -694,7 +678,7 @@ Using `IF NOT EXISTS` when creating the index would result in no error and would [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 +=== 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. @@ -724,7 +708,7 @@ Using `IF NOT EXISTS` when creating the index would result in no error and would [discrete] [[failure-to-create-an-index-when-a-constraint-already-exists]] -==== 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. @@ -752,7 +736,7 @@ There is a uniqueness constraint on (:Book {isbn}), so an index is already creat [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 +=== 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. diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc index a70f9a43a..6ab045748 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc @@ -1,1023 +1,18 @@ -: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 drop indexes used for search performance. += Drop 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] ----- -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) ----- -//// - -.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. +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 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 - -* 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 - -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 *`. - -.Showing all indexes -[source, cypher, role=test-result-skip] ----- -SHOW INDEXES ----- - -// SHOW INDEXES default outputs -// 4.4: id, name, state, populationPercent, uniqueness, type, entityType, labelsOrTypes, properties, indexProvider -// 5.0: id, name, state, populationPercent, type, entityType, labelsOrTypes, properties, indexProvider, owningConstraint -// 5.8: id, name, state, populationPercent, type, entityType, labelsOrTypes, properties, indexProvider, owningConstraint, lastRead, readCount - -.Result -[queryresult] ----- -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint | lastRead | readCount | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 3 | "composite_range_node_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["age", "country"] | "range-1.0" | NULL | NULL | 0 | -| 4 | "composite_range_rel_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["PURCHASED"] | ["date", "amount"] | "range-1.0" | NULL | 2023-03-13T11:41:44.537Z | 1 | -| 16 | "example_index" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["title"] | "range-1.0" | NULL | 2023-04-10T15:41:44.537Z | 2 | -| 17 | "indexOnBooks" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Label1"] | ["prop1"] | "text-2.0" | NULL | NULL | 0 | -| 14 | "node_label_lookup_index" | "ONLINE" | 100.0 | "LOOKUP" | "NODE" | NULL | NULL | "token-lookup-1.0" | NULL | 2023-04-13T08:11:15.537Z | 10 | -| 10 | "node_point_index_name" | "ONLINE" | 100.0 | "POINT" | "NODE" | ["Person"] | ["sublocation"] | "point-1.0" | NULL | 2023-04-05T16:21:44.692Z | 1 | -| 1 | "node_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["surname"] | "range-1.0" | NULL | 2022-12-30T02:01:44.537Z | 6 | -| 6 | "node_text_index_nickname" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Person"] | ["nickname"] | "text-2.0" | NULL | 2023-04-13T11:41:44.537Z | 2 | -| 12 | "point_index_param" | "ONLINE" | 100.0 | "POINT" | "RELATIONSHIP" | ["STREET"] | ["coordinate"] | "point-1.0" | NULL | NULL | 0 | -| 13 | "point_index_with_config" | "ONLINE" | 100.0 | "POINT" | "NODE" | ["Label"] | ["prop2"] | "point-1.0" | NULL | NULL | 0 | -| 5 | "range_index_param" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["firstname"] | "range-1.0" | NULL | 2023-12-13T08:23:53.338Z | 2 | -| 11 | "rel_point_index_name" | "ONLINE" | 100.0 | "POINT" | "RELATIONSHIP" | ["STREET"] | ["intersection"] | "point-1.0" | NULL | 2023-03-03T13:37:42.537Z | 2 | -| 2 | "rel_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["KNOWS"] | ["since"] | "range-1.0" | NULL | 2023-04-12T10:41:44.692Z | 5 | -| 7 | "rel_text_index_name" | "ONLINE" | 100.0 | "TEXT" | "RELATIONSHIP" | ["KNOWS"] | ["interest"] | "text-2.0" | NULL | 2023-04-01T10:40:44.537Z | 3 | -| 15 | "rel_type_lookup_index" | "ONLINE" | 100.0 | "LOOKUP" | "RELATIONSHIP" | NULL | NULL | "token-lookup-1.0" | NULL | 2023-04-12T21:41:44.537Z | 7 | -| 8 | "text_index_param" | "ONLINE" | 100.0 | "TEXT" | "NODE" | ["Person"] | ["favoriteColor"] | "text-2.0" | NULL | NULL | 0 | -| 18 | "uniqueBookIsbn" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["isbn"] | "range-1.0" | "uniqueBookIsbn" | 2023-04-13T11:41:44.692Z | 6 | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -18 rows ----- - -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]. - -[discrete] -[[listing-specific-columns]] -==== Listing specific columns - -It is possible to return only specific columns of the available indexes using the `YIELD` clause: - - -.Returning specific columns for all indexes -[source, cypher, role=test-result-skip] ----- -SHOW INDEXES -YIELD name, type, indexProvider AS provider, options, createStatement -RETURN name, type, provider, options.indexConfig AS config, createStatement ----- - -.Result -[queryresult] ----- -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| name | type | provider | config | createStatement | -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "composite_range_node_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `composite_range_node_index_name` FOR (n:`Person`) ON (n.`age`, n.`country`)" | -| "composite_range_rel_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `composite_range_rel_index_name` FOR ()-[r:`PURCHASED`]-() ON (r.`date`, r.`amount`)" | -| "example_index" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `example_index` FOR (n:`Book`) ON (n.`title`)" | -| "indexOnBooks" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `indexOnBooks` FOR (n:`Label1`) ON (n.`prop1`)" | -| "index_343aff4e" | "LOOKUP" | "token-lookup-1.0" | {} | "CREATE LOOKUP INDEX `index_343aff4e` FOR (n) ON EACH labels(n)" | -| "index_f7700477" | "LOOKUP" | "token-lookup-1.0" | {} | "CREATE LOOKUP INDEX `index_f7700477` FOR ()-[r]-() ON EACH type(r)" | -| "node_point_index_name" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-1000000.0, -1000000.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [1000000.0, 1000000.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `node_point_index_name` FOR (n:`Person`) ON (n.`sublocation`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | -| "node_range_index" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `node_range_index` FOR (n:`Person`) ON (n.`surname`)" | -| "node_text_index_nickname" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `node_text_index_nickname` FOR (n:`Person`) ON (n.`nickname`)" | -| "point_index_with_config" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-100.0, -100.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [100.0, 100.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `point_index_with_config` FOR (n:`Label`) ON (n.`prop2`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [100.0, 100.0],`spatial.cartesian.min`: [-100.0, -100.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | -| "rel_point_index_name" | "POINT" | "point-1.0" | {`spatial.cartesian.min`: [-1000000.0, -1000000.0], `spatial.wgs-84.min`: [-180.0, -90.0], `spatial.wgs-84.max`: [180.0, 90.0], `spatial.cartesian.max`: [1000000.0, 1000000.0], `spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0], `spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0], `spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0], `spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0]} | "CREATE POINT INDEX `rel_point_index_name` FOR ()-[r:`STREET`]-() ON (r.`intersection`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" | -| "rel_range_index_name" | "RANGE" | "range-1.0" | {} | "CREATE RANGE INDEX `rel_range_index_name` FOR ()-[r:`KNOWS`]-() ON (r.`since`)" | -| "rel_text_index_name" | "TEXT" | "text-2.0" | {} | "CREATE TEXT INDEX `rel_text_index_name` FOR ()-[r:`KNOWS`]-() ON (r.`interest`)" | -| "uniqueBookIsbn" | "RANGE" | "range-1.0" | {} | "CREATE CONSTRAINT `uniqueBookIsbn` FOR (n:`Book`) REQUIRE (n.`isbn`) IS UNIQUE" | -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ----- - -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 - -The `SHOW INDEX` command can be filtered in various ways. - -For example, to show only range indexes, use `SHOW RANGE INDEXES`. - -Another more flexible way of filtering the output is to use the `WHERE` clause. -An example is to only show indexes not belonging to constraints. - -To show only range indexes that does not belong to a constraint we can combine the filtering versions. - -.Showing range indexes -[source, cypher, role=test-result-skip] ----- -SHOW RANGE INDEXES WHERE owningConstraint IS NULL ----- - -.Result -[queryresult] ----- -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint | lastRead | readCount | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 3 | "composite_range_node_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["age", "country"] | "range-1.0" | NULL | NULL | 0 | -| 4 | "composite_range_rel_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["PURCHASED"] | ["date", "amount"] | "range-1.0" | NULL | 2023-03-13T11:41:44.537Z | 1 | -| 16 | "example_index" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Book"] | ["title"] | "range-1.0" | NULL | 2023-04-10T15:41:44.537Z | 2 | -| 1 | "node_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["surname"] | "range-1.0" | NULL | 2022-12-30T02:01:44.537Z | 6 | -| 5 | "range_index_param" | "ONLINE" | 100.0 | "RANGE" | "NODE" | ["Person"] | ["firstname"] | "range-1.0" | NULL | 2023-12-13T08:23:53.338Z | 2 | -| 2 | "rel_range_index_name" | "ONLINE" | 100.0 | "RANGE" | "RELATIONSHIP" | ["KNOWS"] | ["since"] | "range-1.0" | NULL | 2023-04-12T10:41:44.692Z | 5 | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -6 rows ----- - -This will only return the default output columns. - -To get all columns, use: - -[source, syntax, role="noheader"] ----- -SHOW RANGE INDEXES YIELD * WHERE owningConstraint IS NULL ----- - -[[listing-indexes-result-columns]] -=== Result columns for listing indexes - -The below table contains the full information about all columns returned by the `SHOW INDEXES YIELD *` command: - -.List indexes output -[options="header", cols="4,6,2"] -|=== -| Column | Description | Type - -| `id` -| The id of the index. label:default-output[] -| `INTEGER` - -| `name` -| Name of the index (explicitly set by the user or automatically assigned). label:default-output[] -| `STRING` - -| `state` -| Current state of the index. label:default-output[] -| `STRING` - -| `populationPercent` -| % of index population. label:default-output[] -| `FLOAT` - -| `type` -| The IndexType of this index (`FULLTEXT`, `LOOKUP`, `POINT`, `RANGE`, `TEXT`, or `VECTOR`). label:default-output[] -| `STRING` - -| `entityType` -| Type of entities this index represents (`NODE` or `RELATIONSHIP`). label:default-output[] -| `STRING` - -| `labelsOrTypes` -| The labels or relationship types of this index. label:default-output[] -| `LIST` - -| `properties` -| The properties of this index. label:default-output[] -| `LIST` - -| `indexProvider` -| The index provider for this index. label:default-output[] -| `STRING` - - -| `owningConstraint` -| The name of the constraint the index is associated with or `null` if the index is not associated with any constraint. label:default-output[] -| `STRING` - -| `lastRead` -| The last time the index was used for reading. -Returns `null` if the index has not been read since `trackedSince`, or if the statistics are not tracked. -label:default-output[] - -| `ZONED DATETIME` - -| `readCount` -| The number of read queries that have been issued to this index since `trackedSince`, or `null` if the statistics are not tracked. label:default-output[] - -| `INTEGER` - -| `trackedSince` -| The time when usage statistics tracking started for this index, or `null` if the statistics are not tracked. - -| `ZONED DATETIME` - -| `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. -| `MAP` - -| `failureMessage` -| The failure description of a failed index. -| `STRING` - -| `createStatement` -| Statement used to create the index. -| `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] @@ -1031,18 +26,18 @@ Instead, an informational notification is returned detailing that the index does [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 +== 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[] -* 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 +=== Drop an index The following statement will attempt to drop the index named `example_index`. @@ -1054,7 +49,7 @@ 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 @@ -1076,9 +71,9 @@ 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 +=== Failure to drop an index backing a constraint It is not possible to drop indexes that back constraints. @@ -1097,9 +92,9 @@ 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 +=== 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`. diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc index 0ebf66f91..300f4292c 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc @@ -1,4 +1,5 @@ :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 @@ -17,9 +18,16 @@ 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). 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[]. +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] + +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. 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/list-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc index 903c86f77..6a3f884c0 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -1,38 +1,30 @@ -: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[] - -= 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]. +:description: This page explains how to list indexes used for search performance. += Show indexes +//// +The below indexes are created in schema/indexes/create-indexes.adoc +[source, cypher, role=test-setup] +---- -[[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 *`. @@ -76,11 +68,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: @@ -119,9 +111,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. @@ -164,7 +156,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: 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 From 84d2de43290600e4ee9b6f3004e27e7c44e62899 Mon Sep 17 00:00:00 2001 From: Richard Sill Date: Wed, 26 Nov 2025 14:16:00 +0100 Subject: [PATCH 3/6] added constraints to the split pages --- .../drop-indexes.adoc | 32 ++++++++++++++++++- .../list-indexes.adoc | 32 ++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc index 6ab045748..0d745164a 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc @@ -9,7 +9,37 @@ The name of the index can be found using the xref:indexes/search-performance-ind 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 $name FOR (n:Person) ON (n.firstname) +CREATE INDEX node_range_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname) +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 $name FOR (n:Person) ON (n.favoriteColor) +CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname) +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 $name FOR ()-[r:STREET]-() ON (r.coordinate) +CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (n:Person) ON (n.sublocation) +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 LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) +CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) +CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) +CREATE INDEX example_index FOR (n:Book) ON (n.title) +CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) +CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) +CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) +CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE +CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) +CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL +CREATE INDEX bookRecommendations FOR (book:Book) ON (book.recommendations) ---- //// diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc index 6a3f884c0..1c6966f24 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -5,7 +5,37 @@ 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 $name FOR (n:Person) ON (n.firstname) +CREATE INDEX node_range_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname) +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 $name FOR (n:Person) ON (n.favoriteColor) +CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname) +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 $name FOR ()-[r:STREET]-() ON (r.coordinate) +CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (n:Person) ON (n.sublocation) +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 LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) +CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) +CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) +CREATE INDEX example_index FOR (n:Book) ON (n.title) +CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) +CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) +CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) +CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE +CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) +CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL +CREATE INDEX bookRecommendations FOR (book:Book) ON (book.recommendations) ---- //// From e2386e326ded7b3b563c2831114a8f963241aaac Mon Sep 17 00:00:00 2001 From: Richard Sill <156673635+rsill-neo4j@users.noreply.github.com> Date: Wed, 26 Nov 2025 16:00:22 +0100 Subject: [PATCH 4/6] Update modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc Co-authored-by: Jessica Wright <49636617+AlexicaWright@users.noreply.github.com> --- .../indexes/search-performance-indexes/create-indexes.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc index 51031b9ff..580d91ae3 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -23,7 +23,9 @@ 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. From a40aaad5c66cd47eeef29eaaafe4f504557daeb1 Mon Sep 17 00:00:00 2001 From: Richard Sill Date: Thu, 27 Nov 2025 17:21:51 +0100 Subject: [PATCH 5/6] review suggestions --- .../create-indexes.adoc | 11 ++++- .../drop-indexes.adoc | 42 +++++++------------ .../search-performance-indexes/index.adoc | 15 ++----- .../list-indexes.adoc | 42 +++++++------------ 4 files changed, 45 insertions(+), 65 deletions(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc index 580d91ae3..214683f70 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -4,6 +4,13 @@ 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. @@ -183,8 +190,8 @@ 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. +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] diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc index 0d745164a..1c8ffc725 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc @@ -9,37 +9,27 @@ The name of the index can be found using the xref:indexes/search-performance-ind 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 $name FOR (n:Person) ON (n.firstname) -CREATE INDEX node_range_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname) -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 $name FOR (n:Person) ON (n.favoriteColor) -CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname) -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 $name FOR ()-[r:STREET]-() ON (r.coordinate) -CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (n:Person) ON (n.sublocation) +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 LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) -CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) -CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) -CREATE INDEX example_index FOR (n:Book) ON (n.title) -CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) -CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) -CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) -CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE -CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) -CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL -CREATE INDEX bookRecommendations FOR (book:Book) ON (book.recommendations) +}; +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; ---- //// diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc index 300f4292c..1b3390789 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc @@ -6,27 +6,20 @@ include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/ascii 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/create-indexes.adoc[], xref:indexes/search-performance-indexes/list-indexes.adoc[] and xref:indexes/search-performance-indexes/drop-indexes.adoc[]. -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] - 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. diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc index 1c6966f24..28a2246d3 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -5,37 +5,27 @@ 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 $name FOR (n:Person) ON (n.firstname) -CREATE INDEX node_range_index_name IF NOT EXISTS FOR (n:Person) ON (n.surname) -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 $name FOR (n:Person) ON (n.favoriteColor) -CREATE TEXT INDEX node_index_name IF NOT EXISTS FOR (n:Person) ON (n.nickname) -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 $name FOR ()-[r:STREET]-() ON (r.coordinate) -CREATE POINT INDEX node_point_index IF NOT EXISTS FOR (n:Person) ON (n.sublocation) +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 LOOKUP INDEX node_label_lookup_index FOR (n) ON EACH labels(n) -CREATE LOOKUP INDEX rel_type_lookup_index FOR ()-[r]-() ON EACH type(r) -CREATE LOOKUP INDEX node_label_lookup IF NOT EXISTS FOR (n) ON EACH labels(n) -CREATE INDEX example_index FOR (n:Book) ON (n.title) -CREATE INDEX bookTitleIndex FOR (book:Book) ON (book.title) -CREATE TEXT INDEX indexOnBooks FOR (b:Label1) ON (b.prop1) -CREATE INDEX indexOnBooks FOR (book:Book) ON (book.numberOfPages) -CREATE CONSTRAINT uniqueBookIsbn FOR (book:Book) REQUIRE (book.isbn) IS UNIQUE -CREATE INDEX bookIsbnIndex FOR (book:Book) ON (book.isbn) -CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) IS NOT NULL -CREATE INDEX bookRecommendations FOR (book:Book) ON (book.recommendations) +}; +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; ---- //// From 91c5fe746c0e03f3b32c38c4ca0fcf09cefabb14 Mon Sep 17 00:00:00 2001 From: Richard Sill Date: Thu, 27 Nov 2025 17:31:29 +0100 Subject: [PATCH 6/6] removed future tense, added admonition markup --- .../create-indexes.adoc | 44 ++++++++++--------- .../drop-indexes.adoc | 10 +++-- .../search-performance-indexes/index.adoc | 2 +- .../list-indexes.adoc | 6 ++- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc index 214683f70..49aefe7ac 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/create-indexes.adoc @@ -35,8 +35,10 @@ Creating an index requires link:{neo4j-docs-base-uri}/operations-manual/current/ ==== [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 @@ -107,7 +109,7 @@ STARTS WITH [[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. +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] @@ -119,7 +121,7 @@ CREATE INDEX node_range_index_name FOR (n:Person) ON (n.surname) [[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`. +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] @@ -132,9 +134,9 @@ CREATE INDEX rel_range_index_name FOR ()-[r:KNOWS]-() ON (r.since) ==== 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. +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 will create a named composite range index on all nodes labeled with `Person` and which have both an `age` and `country` property. +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] @@ -147,9 +149,9 @@ CREATE INDEX composite_range_node_index_name FOR (n:Person) ON (n.age, n.country ==== 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. +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 will create a named composite range index on all relationships labeled with `PURCHASED` and which have both a `date` and `amount` property. +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] @@ -161,7 +163,7 @@ CREATE INDEX composite_range_rel_index_name FOR ()-[r:PURCHASED]-() ON (r.date, [[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. +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] @@ -304,7 +306,7 @@ For more information, see xref:indexes/search-performance-indexes/using-indexes. [[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. +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] @@ -316,7 +318,7 @@ CREATE TEXT INDEX node_text_index_nickname FOR (n:Person) ON (n.nickname) [[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`. +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] @@ -328,7 +330,7 @@ CREATE TEXT INDEX rel_text_index_name FOR ()-[r:KNOWS]-() ON (r.interest) [[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. +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] @@ -350,7 +352,7 @@ CREATE TEXT INDEX $name FOR (n:Person) ON (n.favoriteColor) 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. +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] @@ -358,7 +360,7 @@ The following statement will attempt to create a named text index on all nodes l 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. +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 @@ -431,7 +433,7 @@ To learn more about the spatial data types supported by Cypher, see the page abo [[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. +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] @@ -443,7 +445,7 @@ CREATE POINT INDEX node_point_index_name FOR (n:Person) ON (n.sublocation) [[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`. +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] @@ -455,7 +457,7 @@ CREATE POINT INDEX rel_point_index_name FOR ()-[r:STREET]-() ON (r.intersection) [[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. +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] @@ -484,7 +486,7 @@ 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. +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 @@ -511,7 +513,7 @@ The valid configuration settings are: * `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. +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] @@ -526,7 +528,7 @@ OPTIONS { } ---- -Note that the wgs-84 and 3D cartesian settings, which are not specified in this example, will be set with their respective default values. +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 @@ -594,7 +596,7 @@ Token lookup indexes improve the performance of Cypher queries and the populatio [[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: +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 @@ -612,7 +614,7 @@ Only one node label lookup index can exist at a time. [[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. +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 @@ -638,7 +640,7 @@ If it is not known whether an index exists or not, add `IF NOT EXISTS` to ensure 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. +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 diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc index 1c8ffc725..7ca752573 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/drop-indexes.adoc @@ -44,7 +44,9 @@ With `IF EXISTS`, no error is thrown and nothing happens should the index not ex 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]] @@ -59,7 +61,7 @@ Dropping an index requires link:{neo4j-docs-base-uri}/operations-manual/current/ [[drop-an-index]] === Drop an index -The following statement will attempt to drop the index named `example_index`. +The following statement attempts to drop the index named `example_index`. .Dropping an index [source, cypher] @@ -73,7 +75,7 @@ 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 will attempt to drop the index named `range_index_param` using a parameter for the index name. +The following statement attempts to drop the index named `range_index_param` using a parameter for the index name. .Parameters [source, parameters] @@ -109,7 +111,7 @@ DROP INDEX uniqueBookIsbn Unable to drop index: Index belongs to constraint: `uniqueBookIsbn` ---- -Dropping the index-backed constraint will also remove the backing index. +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]. @@ -118,7 +120,7 @@ For more information, see xref:constraints/managing-constraints.adoc#drop-constr 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`. +The following statement attempts to drop the index named `missing_index_name`. .Dropping an index with `IF EXISTS` [source, cypher] diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc index 1b3390789..aa2795086 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/index.adoc @@ -22,5 +22,5 @@ To learn more about creating, listing, and deleting these indexes, as well as mo 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/list-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc index 28a2246d3..5a5c803c2 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/list-indexes.adoc @@ -32,7 +32,9 @@ CREATE CONSTRAINT bookRecommendations FOR (book:Book) REQUIRE (book.recommend) I 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]. +==== [[listing-indexes-examples]] @@ -166,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: @@ -245,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`