From f48031cc73802f96b1e09fbc7dea317cf7964940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:09:26 +0100 Subject: [PATCH 1/2] Convert Constraint Types to headers (#837) (#838) This would allow us to link users to a specific type of constraint. --------- Co-authored-by: Adam Cowley --- modules/ROOT/pages/constraints/index.adoc | 87 +++++++++++++++-------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/modules/ROOT/pages/constraints/index.adoc b/modules/ROOT/pages/constraints/index.adoc index e79ed3d5d..8b3841160 100644 --- a/modules/ROOT/pages/constraints/index.adoc +++ b/modules/ROOT/pages/constraints/index.adoc @@ -3,47 +3,76 @@ [[constraints]] = Constraints -This page contains an overview of the available constraints in Cypher. +This page contains an overview of the available constraints in Cypher, and information about how constraints can impact indexes. -[[types-of-constraint]] -== Types of constraint +Adding constraints is an atomic operation that can take a while -- all existing data has to be scanned before a Neo4j DBMS can use a constraint. -The following constraint types are available: - -*Unique node property constraints*:: +[[unique-node-property]] +== Unique node property constraints Unique node property constraints, or node property uniqueness constraints, ensure that property values are unique for all nodes with a specific label. For property uniqueness constraints on multiple properties, the combination of the property values is unique. Node property uniqueness constraints do not require all nodes to have a unique value for the properties listed (nodes without all properties on which the constraint exists are not subject to this rule). -*Unique relationship property constraints* label:new[Introduced in 5.7]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-node-uniqueness[examples of node property uniqueness constraints]. + +[[unique-relationship-property]] +== Unique relationship property constraints +label:new[Introduced in 5.7] + Unique relationship property constraints, or relationship property uniqueness constraints, ensure that property values are unique for all relationships with a specific type. For property uniqueness constraints on multiple properties, the combination of the property values is unique. Relationship property uniqueness constraints do not require all relationships to have a unique value for the properties listed (relationships without all properties on which the constraint exists are not subject to this rule). -*Node property existence constraints* label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-relationship-uniqueness[examples of relationship property uniqueness constraints]. + +[[node-property-existence]] +[role=enterprise-edition] +== Node property existence constraints + Node property existence constraints ensure that a property exists for all nodes with a specific label. Queries that try to create new nodes of the specified label, but without this property, will fail. The same is true for queries that try to remove the mandatory property. -*Relationship property existence constraints* label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-node-property-existence[examples of node property existence constraints]. + +[[relationship-property-existence]] +[role=enterprise-edition] +== Relationship property existence constraints + Relationship property existence constraints ensure that a property exists for all relationships with a specific type. All queries that try to create relationships of the specified type, but without this property, will fail. The same is true for queries that try to remove the mandatory property. -*Node property type constraints* label:new[Introduced in 5.9] label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-relationship-property-existence[examples of relationship property existence constraints]. + +[[node-property-type]] +[role=enterprise-edition] +== Node property type constraints +label:new[Introduced in 5.9] + Node property type constraints ensure that a property have the required property type for all nodes with a specific label. Queries that try to add or modify this property to nodes of the specified label, but with a different property type, will fail. Node property type constraints do not require all nodes to have the property (nodes without the property on which the constraint exists are not subject to this rule). -*Relationship property type constraints* label:new[Introduced in 5.9] label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-node-property-type[examples of node property type constraints]. + +[[relationship-property-type]] +[role=enterprise-edition] +== Relationship property type constraints +label:new[Introduced in 5.9] + Relationship property type constraints ensure that a property have the required property type for all relationships with a specific type. Queries that try to add or modify this property to relationships of the specified type, but with a different property type, will fail. Relationship property type constraints do not require all relationships to have the property (relationships without the property on which the constraint exists are not subject to this rule). -*Node key constraints* label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-relationship-property-type[examples of relationship property type constraints]. + +[[node-key]] +[role=enterprise-edition] +== Node key constraints + Node key constraints ensure that, for a given label and set of properties: -+ -[lowerroman] + . All the properties exist on all the nodes with that label. . The combination of the property values is unique. @@ -54,9 +83,15 @@ Queries attempting to do any of the following will fail: * Remove one of the mandatory properties. * Update the properties so that the combination of property values is no longer unique. -*Relationship key constraints* label:new[Introduced in 5.7] label:enterprise-edition[]:: +For more information, see xref:constraints/examples.adoc#constraints-examples-node-key[examples of node key constraints]. + +[[relationship-key]] +[role=enterprise-edition] +== Relationship key constraints +label:new[Introduced in 5.7] + Relationship key constraints ensure that, for a given type and set of properties: -+ + [lowerroman] . All the properties exist on all the relationships with that type. . The combination of the property values is unique. @@ -68,17 +103,17 @@ Queries attempting to do any of the following will fail: * Remove one of the mandatory properties. * Update the properties so that the combination of property values is no longer unique. +For more information, see xref:constraints/examples.adoc#constraints-examples-relationship-key[examples of relationship key constraints]. + +[[multiple-constrains]] +== Multiple constraints on the same property combinations -[NOTE] -==== -Node key constraints, relationship key constraints, node property existence constraints, relationship property existence, node property type constraints, and relationship property type constraints are not available in Neo4j Community Edition. -Databases containing one of these constraint types cannot be opened using Neo4j Community Edition. -==== Some constraint types are allowed on the same label/relationship type and property combination. For example, it is possible to have a uniqueness and an existence constraint on the same label/relationship type and property combination, though this would be the equivalent of having a node or relationship key constraint. A more useful example would be to combine a property type and an existence constraint to ensure that the property exists and has the given type. +[[index-implications]] == Implications on indexes Creating a constraint has the following implications on indexes: @@ -89,13 +124,3 @@ Creating a constraint has the following implications on indexes: Refer to xref:indexes/search-performance-indexes/managing-indexes.adoc[] for more details on indexes. * If a node key, relationship key, or property uniqueness constraint is dropped and the backing index is still required, the index need to be created explicitly. -Additionally, the following is true for constraints: - -* A given label or relationship type can have multiple constraints, and uniqueness and property existence constraints can be combined on the same property. -* Adding constraints is an atomic operation that can take a while -- all existing data has to be scanned before Neo4j DBMS can turn the constraint 'on'. -* Best practice is to give the constraint a name when it is created. -If the constraint is not explicitly named, it will get an auto-generated name. -* The constraint name must be unique among both indexes and constraints. -* Constraint creation is by default not idempotent, and an error will be thrown if you attempt to create the same constraint twice. -Using the keyword `IF NOT EXISTS` makes the command idempotent, and no error will be thrown if you attempt to create the same constraint twice. - From 4fcd9efd53ec4fa220ba55c2140409c5b56c63eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:20:51 +0100 Subject: [PATCH 2/2] Index chapter clean up (#840) --- .../managing-indexes.adoc | 2 +- .../using-indexes.adoc | 7 ++++--- .../semantic-indexes/full-text-indexes.adoc | 12 ++++++++---- .../semantic-indexes/vector-indexes.adoc | 19 +++++++------------ modules/ROOT/pages/indexes/syntax.adoc | 5 +++++ 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc index acb4fcb33..e484fcfae 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/managing-indexes.adoc @@ -1043,7 +1043,7 @@ If an index with that name exists it is removed, if not the command fails. _This feature was introduced in Neo4j 5.16._ -The following statement will attempt to drop the index named `node_range_index_name` using a parameter for the index name. +The following statement will attempt to drop the index named `range_index_param` using a parameter for the index name. .Parameters [source,javascript, indent=0] 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 aab706148..21f28a242 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc @@ -346,7 +346,7 @@ This is especially beneficial when dealing with complex, large geo-spatial data, [[composite-indexes]] == Composite indexes -It is possible to create an index on a single property or multiple properties. +It is possible to create a range index on a single property or multiple properties (text and point indexes are single-property only). The latter are called composite indexes and can be useful if queries against a database frequently filter on _all_ the properties indexed by the composite index. The following example first creates a composite index on `PointOfInterest` nodes for the properties `name` and `type`, and then queries the graph using the xref:patterns/concepts.adoc#shortest-path[shortestPath function] to determine both the path length (in terms of traversed relationships in the graph) and geographical distance between the `Zoo School` and its nearest `tennis pitch` (note that there are 32 unique `PointOfInterest` `tennis pitch` nodes in the graph): @@ -360,6 +360,7 @@ CREATE INDEX composite_index FOR (n:PointOfInterest) ON (n.name, n.type) .Query with a filter on both properties indexed by the composite index [source,cypher] ---- +PROFILE MATCH (tennisPitch: PointOfInterest {name: 'tennis', type: 'pitch'}) WITH tennisPitch MATCH path = shortestPath((tennisPitch)-[:ROUTE*]-(:PointOfInterest {name: 'Zoo School'})) @@ -538,7 +539,7 @@ These rules can be important when creating composite indexes, as some checks are For instance, it is generally more efficient for the planner to perform an equality check on a property than an existence check. Depending on the queries and the application, it may, therefore, be cost-effective to consider the order in which properties are defined when creating a composite index. -Additionally, it bears repeating that composite indexes can only be used if a predicate filters on all the properties indexed by the composite index, and that composite indexes can only be created for range indexes (point and text indexes are single-property only). +Additionally, it bears repeating that composite indexes can only be used if a predicate filters on all the properties indexed by the composite index, and that composite indexes can only be created for range indexes. [[range-index-backed-order-by]] == Range index-backed ORDER BY @@ -1005,7 +1006,7 @@ The order in which the properties are defined when creating a composite index im * A Cypher query can use several indexes if the planner deems it beneficial to the performance of a query. -* * Neo4j indexes do not store `null` values, and the planner must be able to rule out any entities with properties containing `null` values in order to use an index. +* Neo4j indexes do not store `null` values, and the planner must be able to rule out any entities with properties containing `null` values in order to use an index. There are several strategies to ensure the use of indexes. * The columns `lastRead`, `readCount`, and `trackedSince` returned by the `SHOW INDEX` command can be used to identify redundant indexes that take up unnecessary space. 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 769ed3cf6..cf199c306 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/full-text-indexes.adoc @@ -31,13 +31,19 @@ CREATE (nilsE:Employee {name: "Nils-Erik Karlsson", position: "Engineer", team: == Create full-text indexes Full-text indexes are created with the `CREATE FULLTEXT INDEX` command. -An index can be given a unique name when created, which is used to reference the index when querying or dropping it. +It is recommended to to give the index a name when it is created. If no name is given when created, a random name will be assigned to the full-text index. -When creating a full-text index, you need to specify the labels/relationship types and property names it should apply to. + +The `CREATE FULLTEXT 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 a full-text index on the same schema already exist. +As of Neo4j 5.16, the index name can also be given as a parameter, `CREATE FULLTEXT INDEX $name FOR ...`. [TIP] Creating a full-text index requires the link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/database-administration/#access-control-database-administration-index[`CREATE INDEX` privilege]. +When creating a full-text index, you need to specify the labels/relationship types and property names it should apply to. + This statement creates a full-text index named `namesAndTeams` on each `name` and `team` property for nodes with the label `Employee` or `Manager`: .Create a full-text index on a node label and property combination @@ -62,8 +68,6 @@ This statement creates a full-text index named `communications` on the `message` CREATE FULLTEXT INDEX communications FOR ()-[r:REVIEWED|EMAILED]-() ON EACH [r.message] ---- -Full-text indexes follow the same xref:indexes/index.adoc#naming-rules-and-recommendations[naming rules and best-practices] as search-performance indexes. - [[tokenization-analyzers]] === Tokenization and analyzers diff --git a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc index a37e482a8..e867a33a1 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc @@ -11,7 +11,7 @@ :l2-norm: image:l2.svg["l2"]-norm [[indexes-vector]] -= Vector search index += Vector search indexes _Vector search indexes were released as a public beta in Neo4j 5.11 and general availability in Neo4j 5.13._ @@ -93,10 +93,6 @@ A vector index is a single-label, single-property index for nodes. A vector index needs to be configured with both the dimensionality of the vector (`INTEGER` between `1` and `2048` _inclusive_), and the measure of similarity between two vectors (case-insensitive `STRING`). For details, see xref:#indexes-vector-similarity[]. -[NOTE] -==== -More details about the syntax descriptions can be found link:{neo4j-docs-base-uri}/operations-manual/{page-version}/database-administration/syntax/#administration-syntax-reading[here]. -==== .Syntax for creating vector indexes [options="header", width="100%", cols="5a, 3"] @@ -296,8 +292,6 @@ A vector index is dropped by using the xref:indexes/search-performance-indexes/m Dropping a vector index requires link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/database-administration/#access-control-database-administration-index[the `DROP INDEX` privilege]. -Dropping a vector index requires link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/database-administration/#access-control-database-administration-index[the `DROP INDEX` privilege]. - .+DROP INDEX+ ====== @@ -343,12 +337,12 @@ db.create.setVectorProperty(node :: NODE, key :: STRING, vector :: LIST) The following example shows how to define embeddings as Cypher parameters by matching a node and setting its vector properties using `db.create.setNodeVectorProperty`: -.Set a vector via `db.create.setVectorProperty` +.Set a vector via `db.create.setNodeVectorProperty` [source,cypher] ---- MATCH (n:Node {id: $id}) CALL db.create.setNodeVectorProperty(n, 'propertyKey', $vector) -RETURN node +RETURN n ---- Furthermore, you can also use a list parameter containing several `MATCH` criteria and embeddings to update multiple nodes in an `UNWIND` clause. @@ -437,9 +431,6 @@ The requested _k_ nearest neighbors may not be the exact _k_ nearest, but close * For large requested nearest neighbors, _k_, close to the total number of indexed vectors, the search may retrieve fewer than _k_ results. -* The index must have a unique name. -There is no provided method for an autogenerated name. - * Only one vector index can be over a schema. For example, you cannot have one xref:indexes-vector-similarity-euclidean[Euclidean] and one xref:indexes-vector-similarity-cosine[cosine] vector index on the same label-property key pair. @@ -459,6 +450,10 @@ The following table lists the known issues and the version in which they were fi |=== | Known issues | Fixed in +| Vector indexes cannot be assigned autogenerated names. + +| Neo4j 5.15 + | There is no Cypher syntax for creating a vector index. [TIP] diff --git a/modules/ROOT/pages/indexes/syntax.adoc b/modules/ROOT/pages/indexes/syntax.adoc index 777ef49de..52cf1d6b7 100644 --- a/modules/ROOT/pages/indexes/syntax.adoc +++ b/modules/ROOT/pages/indexes/syntax.adoc @@ -4,6 +4,8 @@ This page contains the syntax for creating, listing, and dropping the indexes available in Neo4j. It also contains the signatures for the procedures necessary to call in order to use full-text and vector indexes. +More details about the syntax can be found in the link:{neo4j-docs-base-uri}/operations-manual/{page-version}/database-administration/syntax/[Operations Manual -> Cypher syntax for administration commands]. + [[create-index]] == CREATE INDEX @@ -263,6 +265,9 @@ The `query` vector refers to the `LIST` in which to search for the neighb [[drop-index]] == DROP INDEX +The `DROP INDEX` command can drop indexes of all types using their name. +The name of the index can be found using the `SHOW INDEXES` command, given in the output column `name`. + The `DROP INDEX` command is optionally idempotent. This means that its default behavior is to throw an error if an attempt is made to drop the same index twice. With `IF EXISTS`, no error is thrown and nothing happens should the index not exist.