创建、显示和删除约束

此页面介绍如何创建、列出和删除约束。Neo4j 中提供以下约束类型

CREATE CONSTRAINT

使用 CREATE CONSTRAINT 命令创建约束。创建约束时,建议提供约束名称。此名称在索引和约束中必须唯一。如果未明确给出名称,则会自动生成唯一名称。

创建约束需要 CREATE CONSTRAINT 权限.
添加约束是原子操作,可能需要一段时间才能完成——Neo4j DBMS 必须扫描所有现有数据才能使用约束。

创建属性唯一性约束

属性唯一性约束确保属性值对具有特定标签的所有节点或具有特定类型的全部关系是唯一的。对于多个属性的复合属性唯一性约束,属性值的组合必须唯一。尝试添加重复属性值的查询将失败。

属性唯一性约束不要求所有节点或关系都具有约束中列出的属性值。只有包含约束中指定的所有属性的节点或关系才受唯一性规则约束。缺少一个或多个指定属性的节点或关系不受此规则约束。

创建单个属性唯一性约束

单个属性唯一性约束使用以下命令创建

  • 节点属性唯一性约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE n.property IS UNIQUE.

  • 关系属性唯一性约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE r.property IS UNIQUE. 在 5.7 中引入

有关创建属性唯一性约束的完整命令语法,请参见 语法 → 创建属性唯一性约束.

示例 1. 在单个属性上创建节点属性唯一性约束
创建一个约束,要求 Book 节点具有唯一的 isbn 属性
CREATE CONSTRAINT book_isbn
FOR (book:Book) REQUIRE book.isbn IS UNIQUE
结果
Added 1 constraint.
详细统计视图目前显示 Unique constraints added: 1。它将在 Neo4j 的未来版本中更新为显示 Node property uniqueness constraints added: 1
示例 2. 在单个属性上创建关系属性唯一性约束 在 5.7 中引入
创建一个约束,要求 SEQUEL_OF 关系具有唯一的 order 属性
CREATE CONSTRAINT sequels
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE
结果
Added 1 constraint.
详细统计视图目前显示 Relationship uniqueness constraints added: 1。它将在 Neo4j 的未来版本中更新为显示 Relationship property uniqueness constraints added: 1

创建复合属性唯一性约束

为多个属性创建的约束称为复合约束。请注意,在创建复合属性唯一性约束时,约束属性必须用括号括起来。

  • 节点属性唯一性约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE (n.propertyName_1, …​, n.propertyName_n) IS UNIQUE.

  • 关系属性唯一性约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE (r.propertyName_1, …​, r.propertyName_n) IS UNIQUE. 在 5.7 中引入

有关创建属性唯一性约束的完整命令语法,请参见 语法 → 创建属性唯一性约束.

示例 3. 在多个属性上创建复合节点属性唯一性约束
创建一个约束,要求 Book 节点具有唯一的 titlepublicationYear 属性组合
CREATE CONSTRAINT book_title_year
FOR (book:Book) REQUIRE (book.title, book.publicationYear) IS UNIQUE
结果
Added 1 constraint.
示例 4. 在多个属性上创建复合关系属性唯一性约束 在 5.7 中引入
创建一个约束,要求 PREQUEL_OF 关系具有唯一的 orderauthor 属性组合
CREATE CONSTRAINT prequels
FOR ()-[prequel:PREQUEL_OF]-() REQUIRE (prequel.order, prequel.author) IS UNIQUE
结果
Added 1 constraint.

创建符合现有属性唯一性约束的数据

示例 5. 创建符合现有属性唯一性约束的节点
创建一个 Book 节点,其 isbn 属性唯一
CREATE (book:Book {isbn: '1449356265', title: 'Graph Databases'})
结果
Added 1 label, created 1 node, set 2 properties
示例 6. 创建符合现有属性唯一性约束的关系
创建一个 SEQUEL_OF 关系,其 order 属性唯一
CREATE (:Book {title: 'Spirit Walker'})-[:SEQUEL_OF {order: 1, seriesTitle: 'Chronicles of Ancient Darkness'}]->(:Book {title: 'Wolf Brother'})
结果
Added 2 labels, created 2 nodes, set 4 properties, created 1 relationship.

创建属性存在约束

属性存在约束确保属性存在于所有具有特定标签的节点或所有具有特定类型的关系中。尝试创建没有约束属性的指定标签的新节点或指定类型的关系的查询将失败。对于尝试删除强制属性的查询,也是如此。

创建单个属性存在约束

单个属性的属性存在约束使用以下命令创建

  • 节点属性存在约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE n.property IS NOT NULL.

  • 关系属性存在约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE r.property IS NOT NULL.

有关创建存在约束的完整命令语法,请参见 语法 → 创建属性存在约束.

无法在多个属性上创建复合存在约束。
示例 7. 创建节点属性存在约束
创建一个约束,要求 Author 节点具有 name 属性
CREATE CONSTRAINT author_name
FOR (author:Author) REQUIRE author.name IS NOT NULL
结果
Added 1 constraint.
示例 8. 创建一个关系属性存在约束
创建一个约束,要求 WROTE 关系必须具有 year 属性
CREATE CONSTRAINT wrote_year
FOR ()-[wrote:WROTE]-() REQUIRE wrote.year IS NOT NULL
结果
Added 1 constraint.

创建符合现有属性存在约束的数据

示例 9. 创建一个符合现有节点属性存在约束的节点
创建一个带有 name 属性的 Author 节点
CREATE (author:Author {name:'Virginia Woolf', surname: 'Woolf'})
结果
Added 1 label, created 1 node, set 2 properties
示例 10. 创建一个符合现有关系属性存在约束的关系
创建一个带有 year 属性的 WROTE 关系
CREATE (author:Author {name: 'Emily Brontë', surname: 'Brontë'})-[wrote:WROTE {year: 1847, location: 'Haworth, United Kingdom', published: true}]->(book:Book {title:'Wuthering Heights', isbn: 9789186579296})
结果
Added 2 labels, created 2 nodes, set 7 properties, created 1 relationship

创建属性类型约束

属性类型约束确保属性对所有具有特定标签的节点或所有具有特定类型的关系都具有必需的数据类型。尝试使用错误的数据类型添加此属性或以更改指定标签的节点或指定类型的关系的数据类型的形式修改此属性的查询将失败。

属性类型约束不要求所有节点或关系都具有该属性。没有受约束属性的节点或关系不受此规则约束。

创建一个单一属性类型约束

属性类型约束使用以下命令创建

  • 节点属性类型约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE n.property IS :: <TYPE>.

  • 关系属性类型约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE r.property IS :: <TYPE>.

<TYPE> 指的是特定 Cypher® 数据类型,例如 STRINGINTEGER。有关可以约束属性的类型,请参见 允许的类型,有关 Cypher 中不同数据类型的更多信息,请参见 值和类型。有关创建属性类型约束的完整命令语法,请参见 语法 → 创建属性类型约束.

无法在多个属性上创建复合属性类型约束。
示例 11. 创建一个节点属性类型约束
创建一个约束,要求 Movie 节点上的 title 属性为 STRING 类型
CREATE CONSTRAINT movie_title
FOR (movie:Movie) REQUIRE movie.title IS :: STRING
结果
Added 1 constraint.
示例 12. 创建一个关系属性类型约束
创建一个约束,要求 PART_OF 关系上的 order 属性为 INTEGER 类型
CREATE CONSTRAINT part_of
FOR ()-[part:PART_OF]-() REQUIRE part.order IS :: INTEGER
结果
Added 1 constraint.

创建具有联合类型的属性类型约束

封闭动态联合允许节点或关系属性保持一些类型灵活性,同时防止意外值被存储。

示例 13. 创建一个具有联合类型的节点属性类型约束
创建一个约束,要求 Movie 节点上的 tagline 属性为 STRING 类型或 LIST<STRING NOT NULL> 类型
CREATE CONSTRAINT movie_tagline
FOR (movie:Movie) REQUIRE movie.tagline IS :: STRING | LIST<STRING NOT NULL>
结果
Added 1 constraint.
示例 14. 创建一个具有联合类型的关系属性类型约束
创建一个约束,要求 PART_OF 关系上的 tags 属性为 STRING 类型或 LIST<STRING NOT NULL> 类型
CREATE CONSTRAINT part_of_tags
FOR ()-[part:PART_OF]-() REQUIRE part.tags IS :: STRING | LIST<STRING NOT NULL>
结果
Added 1 constraint.

允许的类型

属性类型约束允许的属性类型为

  • BOOLEAN

  • STRING

  • INTEGER

  • FLOAT

  • DATE

  • LOCAL TIME

  • ZONED TIME

  • LOCAL DATETIME

  • ZONED DATETIME

  • DURATION

  • POINT

  • LIST<BOOLEAN NOT NULL> 在 5.10 中引入

  • LIST<STRING NOT NULL> 在 5.10 中引入

  • LIST<INTEGER NOT NULL> 在 5.10 中引入

  • LIST<FLOAT NOT NULL> 在 5.10 中引入

  • LIST<DATE NOT NULL> 在 5.10 中引入

  • LIST<LOCAL TIME NOT NULL> 在 5.10 中引入

  • LIST<ZONED TIME NOT NULL> 在 5.10 中引入

  • LIST<LOCAL DATETIME NOT NULL> 在 5.10 中引入

  • LIST<ZONED DATETIME NOT NULL> 在 5.10 中引入

  • LIST<DURATION NOT NULL> 在 5.10 中引入

  • LIST<POINT NOT NULL> 在 5.10 中引入

  • 上述类型的任何封闭动态联合,例如 INTEGER | FLOAT | STRING在 5.11 中引入

有关描述 Cypher 中所有可用类型的完整参考,请参见关于 类型及其同义词 的部分。

在无效类型上创建属性类型约束将失败

示例 15. 使用无效类型创建节点属性类型约束
创建一个约束,要求 Movie 节点上的 imdbScore 属性为 MAP 类型
CREATE CONSTRAINT score FOR (movie:Movie) REQUIRE movie.imdbScore IS :: MAP
错误信息
Failed to create node property type constraint: Invalid property type `MAP`.

创建符合现有属性类型约束的数据

示例 16. 创建一个符合现有节点属性类型约束的节点
创建一个带有 STRING 类型的 title 属性的 Movie 节点
CREATE (movie:Movie {title:'Iron Man'})
结果
Added 1 label, created 1 node, set 1 properties
示例 17. 创建一个符合现有关系属性类型约束的关系
创建一个带有 INTEGER 类型的 order 属性的 PART_OF 关系
MATCH (movie:Movie {title:'Iron Man'})
CREATE (movie)-[part:PART_OF {order: 3}]->(franchise:Franchise {name:'MCU'})
结果
Added 1 label, added 1 node, created 1 relationship, set 2 properties

创建键约束

键约束确保属性存在并且属性值对所有具有特定标签的节点或所有具有特定类型的关系都是唯一的。对于多个属性的复合键约束,所有属性必须存在,并且属性值的组合必须是唯一的。

尝试创建指定标签的新节点或指定类型的关系但不具有受约束属性的查询将失败。对于尝试删除强制属性或添加重复属性值的查询,也是如此。

创建一个单一属性键约束

单一属性键约束使用以下命令创建

  • 节点键约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE n.property IS NODE KEY.

  • 关系键约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE r.property IS RELATIONSHIP KEY在 5.7 中引入

有关创建键约束的完整命令语法,请参见 语法 → 创建键约束.

示例 18. 创建一个单一属性上的节点键约束
创建一个约束,要求 Director 节点必须具有唯一的 imdbId 属性作为节点键。
CREATE CONSTRAINT director_imdbId
FOR (director:Director) REQUIRE (director.imdbId) IS NODE KEY
结果
Added 1 constraint.
示例 19. 创建一个单一属性上的关系键约束 在 5.7 中引入
创建一个约束,要求 OWNS 关系必须具有唯一的 ownershipId 属性作为关系键
CREATE CONSTRAINT ownershipId
FOR ()-[owns:OWNS]-() REQUIRE owns.ownershipId IS RELATIONSHIP KEY
结果
Added 1 constraint.

创建复合键约束

为多个属性创建的约束称为复合约束。请注意,在创建复合键约束时,受约束的属性必须用括号括起来。

复合键约束使用以下命令创建

  • 节点键约束:CREATE CONSTRAINT constraint_name FOR (n:Label) REQUIRE (n.propertyName_1, …​, n.propertyName_n) IS NODE KEY.

  • 关系键约束:CREATE CONSTRAINT constraint_name FOR ()-[r:REL_TYPE]-() REQUIRE (r.propertyName_1, …​, r.propertyName_n) IS RELATIONSHIP KEY在 5.7 中引入

有关创建键约束的完整命令语法,请参见 语法 → 创建键约束.

示例 20. 在多个属性上创建复合节点键约束
创建一个约束,要求 Actor 节点必须具有唯一的 firstnamesurname 属性组合作为节点键
CREATE CONSTRAINT actor_fullname
FOR (actor:Actor) REQUIRE (actor.firstname, actor.surname) IS NODE KEY
结果
Added 1 constraint.
示例 21. 在多个属性上创建复合关系键约束标签 在 5.7 中引入
创建一个约束,要求 KNOWS 关系必须具有唯一的 sincehow 属性组合作为关系键
CREATE CONSTRAINT knows_since_how
FOR ()-[knows:KNOWS]-() REQUIRE (knows.since, knows.how) IS RELATIONSHIP KEY
结果
Added 1 constraint.

创建符合现有键约束的数据

示例 22. 创建一个符合现有节点键约束的节点
创建一个带有唯一的 firstnamesurname 属性的 Actor 节点
CREATE (actor:Actor {firstname: 'Keanu', surname: 'Reeves'})
结果
Added 1 label, created 1 node, set 2 properties.
示例 23. 创建一个符合现有关系键约束的关系
创建一个带有唯一的 sincehow 属性的 KNOWS 关系
CREATE (:Actor {firstname: 'Jensen', surname: 'Ackles'})-[:KNOWS {since: 2008, how: 'coworkers', friend: true}]->(:Actor {firstname: 'Misha', surname: 'Collins'})
结果
Added 2 labels, created 2 nodes, set 7 properties, created 1 relationship.

使用参数创建约束

所有约束类型都可以使用参数化名称创建。

示例 24. 使用参数创建节点属性唯一性约束
参数
{
  "name": "node_uniqueness_param"
}
使用参数化名称创建节点属性唯一性约束
CREATE CONSTRAINT $name
FOR (book:Book) REQUIRE book.prop1 IS UNIQUE
结果
Added 1 constraint.
示例 25. 使用参数创建关系属性存在约束
参数
{
  "name": "rel_exist_param"
}
使用参数化名称创建关系属性存在约束
CREATE CONSTRAINT $name
FOR ()-[wrote:WROTE]-() REQUIRE wrote.published IS NOT NULL
结果
Added 1 constraint.

处理多个约束

创建已经存在的约束将失败。这包括以下场景

  • 创建与已经存在的约束相同的约束。

  • 创建具有不同名称的约束,但使用与已经存在的约束相同的约束类型以及相同的标签/关系类型和属性组合。对于属性类型约束,属性类型也需要相同。

  • 创建与现有约束同名的约束,无论该约束是什么。

此外,一些约束不能共存,尝试同时创建它们也会失败。这包括:

  • 相同标签/关系类型和属性,但属性类型不同的属性类型约束。

  • 相同标签/关系类型和属性组合的属性唯一性和键约束。

但是,某些约束类型允许在相同标签/关系类型和属性组合上。例如,可以在相同标签/关系类型和属性组合上同时拥有属性唯一性和属性存在约束,但这等同于拥有节点或关系键约束。一个更有用的例子是将属性类型和属性存在约束结合起来,以确保属性存在且具有给定的类型。

创建约束时处理现有约束

为了避免在现有约束上失败,可以在 CREATE 命令中添加 IF NOT EXISTS。这将确保不会抛出错误,并且如果任何其他具有给定名称的约束,或相同约束类型和模式上的其他约束,或两者都已存在,则不会创建任何约束。对于属性类型约束,属性类型也需要相同。从 Neo4j 5.17 开始,将返回一个信息通知,显示阻止创建的现有约束。

示例 26. 创建与现有约束相同的约束
创建一个约束,要求所有 SEQUEL_OF 关系具有唯一的 order 属性
CREATE CONSTRAINT sequels IF NOT EXISTS
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE

由于相同的约束已经存在,因此不会发生任何事情

结果
(no changes, no records)
通知
`CREATE CONSTRAINT sequels IF NOT EXISTS FOR ()-[e:SEQUEL_OF]-() REQUIRE (e.order) IS UNIQUE` has no effect.
`CONSTRAINT sequels FOR ()-[e:SEQUEL_OF]-() REQUIRE (e.order) IS UNIQUE` already exists.
示例 27. 当具有不同名称的相同约束已存在时,创建关系属性唯一性约束
创建一个约束,要求所有 SEQUEL_OF 关系具有唯一的 order 属性
CREATE CONSTRAINT new_sequels IF NOT EXISTS
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE

由于在相同模式上存在一个具有不同名称 (sequels) 的约束,因此不会发生任何事情

结果
(no changes, no records)
通知
`CREATE CONSTRAINT new_sequels IF NOT EXISTS FOR ()-[e:SEQUEL_OF]-() REQUIRE (e.order) IS UNIQUE` has no effect.
`CONSTRAINT sequels FOR ()-[e:SEQUEL_OF]-() REQUIRE (e.order) IS UNIQUE` already exists.
示例 28. 创建与现有约束类型不同的关系属性唯一性约束
创建一个约束,要求所有 AUTHORED 关系具有唯一的 name 属性
CREATE CONSTRAINT author_name IF NOT EXISTS
FOR ()-[a:AUTHORED]-() REQUIRE a.name IS UNIQUE

由于已经存在名为 author_name 的节点属性存在约束,因此不会发生任何事情

结果
(no changes, no records)
通知
`CREATE CONSTRAINT author_name IF NOT EXISTS FOR ()-[e:AUTHORED]-() REQUIRE (e.name) IS UNIQUE` has no effect.
`CONSTRAINT author_name FOR (e:Author) REQUIRE (e.name) IS NOT NULL` already exists.

创建现有约束将失败

使用与已受相同类型约束的节点标签或关系类型和属性相同名称或在相同节点标签或关系类型和属性上创建约束将失败。属性唯一性和键约束也不允许在同一模式上。

示例 29. 创建与现有约束相同的约束
创建一个约束,要求所有 SEQUEL_OF 关系具有唯一的 order 属性,假设已经存在相同的约束
CREATE CONSTRAINT sequels
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE
错误信息
An equivalent constraint already exists, 'Constraint( id=5, name='sequels', type='RELATIONSHIP UNIQUENESS', schema=()-[:SEQUEL_OF {order}]-(), ownedIndex=4 )'.
在未来的 Neo4j 版本中,约束类型将更新为 RELATIONSHIP PROPERTY UNIQUENESS
示例 30. 创建具有不同名称但与现有约束位于相同模式上的约束
创建一个约束,要求所有 Book 节点具有唯一的 isbn 属性,假设在该模式上已经存在约束
CREATE CONSTRAINT new_book_isbn
FOR (book:Book) REQUIRE book.isbn IS UNIQUE
错误信息
Constraint already exists: Constraint( id=3, name='book_isbn', type='UNIQUENESS', schema=(:Book {isbn}), ownedIndex=2 )
在未来的 Neo4j 版本中,约束类型将更新为 NODE PROPERTY UNIQUENESS
示例 31. 创建具有相同名称但与现有约束位于不同模式上的约束
创建一个约束,要求所有 AUTHORED 关系具有唯一的 name 属性,假设在不同模式上已经存在具有相同名称的约束
CREATE CONSTRAINT author_name
FOR ()-[a:AUTHORED]-() REQUIRE a.name IS UNIQUE
错误信息
There already exists a constraint called 'author_name'.
示例 32. 在已存在将属性约束到不同类型的属性类型约束的情况下,在属性上创建属性类型约束
创建一个约束,要求 PART_OF 关系上的 order 属性为 FLOAT 类型,假设已经存在一个约束,要求相同的属性为 INTEGER 类型
CREATE CONSTRAINT new_part_of
FOR ()-[part:PART_OF]-() REQUIRE part.order IS :: FLOAT
错误信息
Conflicting constraint already exists: Constraint( id=21, name='part_of', type='RELATIONSHIP PROPERTY TYPE', schema=()-[:PART_OF {order}]-(), propertyType=INTEGER )
示例 33. 在与现有属性唯一性约束位于相同模式上创建节点键约束
在已在相同标签和属性组合上存在属性唯一性约束的情况下,在具有 Book 标签的节点上的 titlepublicationYear 属性上创建节点键约束
CREATE CONSTRAINT book_titles FOR (book:Book) REQUIRE (book.title, book.publicationYear) IS NODE KEY
错误信息
Constraint already exists: Constraint( id=7, name='book_title_year', type='UNIQUENESS', schema=(:Book {title, publicationYear}), ownedIndex=6 )

约束和索引

约束和支持索引

属性唯一性约束和键约束由 范围索引 支持。这意味着创建属性唯一性或键约束将创建一个范围索引,其名称、节点标签/关系类型和属性组合与其所属约束相同。单属性约束将创建单属性索引,多属性复合约束将创建 复合索引

不能单独添加相同索引类型、标签/关系类型和属性组合的索引。但是,删除属性唯一性或键约束也将删除其支持索引。如果仍然需要支持索引,则需要显式重新创建索引。

属性唯一性和键约束需要索引,因为它允许系统快速检查是否存在具有相同标签和属性值的节点或具有相同类型和属性值的关联。如果没有索引,系统将需要扫描所有具有相同标签的节点,这将很慢且效率低下,尤其是在图增长时。索引通过启用直接查找而不是扫描整个图来使这些检查更快。Cypher 将以与利用其他搜索性能索引相同的方式使用具有所属约束的索引。有关索引如何影响查询性能的更多信息,请参阅 索引对查询性能的影响

这些索引在 SHOW INDEX 命令返回的 owningConstraint 列中列出,并且在 SHOW CONSTRAINT 命令返回的 ownedIndex 列中列出。

示例 34. 列出具有支持索引的约束
查询
SHOW CONSTRAINTS WHERE ownedIndex IS NOT NULL
结果
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                    | type                      | entityType     | labelsOrTypes  | properties                   | ownedIndex              | propertyType |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 21 | "actor_fullname"        | "NODE_KEY"                | "NODE"         | ["Actor"]      | ["firstname", "surname"]     | "actor_fullname"        | NULL         |
| 3  | "book_isbn"             | "UNIQUENESS"              | "NODE"         | ["Book"]       | ["isbn"]                     | "book_isbn"             | NULL         |
| 7  | "book_title_year"       | "UNIQUENESS"              | "NODE"         | ["Book"]       | ["title", "publicationYear"] | "book_title_year"       | NULL         |
| 17 | "director_imdbId"       | "NODE_KEY"                | "NODE"         | ["Director"]   | ["imdbId"]                   | "director_imdbId"       | NULL         |
| 23 | "knows_since_how"       | "RELATIONSHIP_KEY"        | "RELATIONSHIP" | ["KNOWS"]      | ["since", "how"]             | "knows_since_how"       | NULL         |
| 25 | "node_uniqueness_param" | "UNIQUENESS"              | "NODE"         | ["Book"]       | ["prop1"]                    | "node_uniqueness_param" | NULL         |
| 19 | "ownershipId"           | "RELATIONSHIP_KEY"        | "RELATIONSHIP" | ["OWNS"]       | ["ownershipId"]              | "ownershipId"           | NULL         |
| 9  | "prequels"              | "RELATIONSHIP_UNIQUENESS" | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"]          | "prequels"              | NULL         |
| 5  | "sequels"               | "RELATIONSHIP_UNIQUENESS" | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order"]                    | "sequels"               | NULL         |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例 35. 列出具有所属约束的索引
查询
SHOW INDEXES WHERE owningConstraint IS NOT NULL
结果
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                    | state    | populationPercent | type    | entityType     | labelsOrTypes  | properties                   | indexProvider | owningConstraint        | lastRead                 | readCount |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 20 | "actor_fullname"        | "ONLINE" | 100.0             | "RANGE" | "NODE"         | ["Actor"]      | ["firstname", "surname"]     | "range-1.0"   | "actor_fullname"        | 2024-10-07T12:12:51.893Z | 3         |
| 2  | "book_isbn"             | "ONLINE" | 100.0             | "RANGE" | "NODE"         | ["Book"]       | ["isbn"]                     | "range-1.0"   | "book_isbn"             | 2024-10-07T11:58:09.252Z | 2         |
| 6  | "book_title_year"       | "ONLINE" | 100.0             | "RANGE" | "NODE"         | ["Book"]       | ["title", "publicationYear"] | "range-1.0"   | "book_title_year"       | NULL                     | 0         |
| 16 | "director_imdbId"       | "ONLINE" | 100.0             | "RANGE" | "NODE"         | ["Director"]   | ["imdbId"]                   | "range-1.0"   | "director_imdbId"       | NULL                     | 0         |
| 22 | "knows_since_how"       | "ONLINE" | 100.0             | "RANGE" | "RELATIONSHIP" | ["KNOWS"]      | ["since", "how"]             | "range-1.0"   | "knows_since_how"       | 2024-10-07T12:12:51.894Z | 1         |
| 24 | "node_uniqueness_param" | "ONLINE" | 100.0             | "RANGE" | "NODE"         | ["Book"]       | ["prop1"]                    | "range-1.0"   | "node_uniqueness_param" | NULL                     | 0         |
| 18 | "ownershipId"           | "ONLINE" | 100.0             | "RANGE" | "RELATIONSHIP" | ["OWNS"]       | ["ownershipId"]              | "range-1.0"   | "ownershipId"           | NULL                     | 0         |
| 8  | "prequels"              | "ONLINE" | 100.0             | "RANGE" | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"]          | "range-1.0"   | "prequels"              | NULL                     | 0         |
| 4  | "sequels"               | "ONLINE" | 100.0             | "RANGE" | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order"]                    | "range-1.0"   | "sequels"               | 2024-10-07T11:57:12.999Z | 1         |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
属性存在和属性类型约束不受索引支持。

使用索引提供程序创建约束

由于属性唯一性和键约束具有支持索引,因此在使用 OPTIONS 子句和 indexProvider 选项创建这些约束时,可以提供索引提供程序。

索引提供程序的唯一有效值为:

  • range-1.0 默认

示例 36. 使用指定的索引提供程序创建节点键约束
创建一个约束,要求 Actor 节点具有唯一的 surname 属性作为节点键,指定 range-1.0 作为索引提供程序
CREATE CONSTRAINT constraint_with_provider
FOR (actor:Actor) REQUIRE actor.surname IS NODE KEY
OPTIONS {
  indexProvider: 'range-1.0'
}
结果
Added 1 constraint.
示例 37. 使用指定的索引提供程序创建关系属性唯一性约束
创建一个约束,要求 SEQUEL_OF 关系具有 orderseriesTitlenumber 属性的唯一组合,指定 range-1.0 作为索引提供程序
CREATE CONSTRAINT rel_constraint_with_options
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE (sequel.order, sequel.seriesTitle, sequel.number) IS UNIQUE
OPTIONS {
  indexProvider: 'range-1.0'
}
结果
Added 1 constraint.

约束支持范围索引没有有效的索引配置值。

约束失败和索引

尝试使用与现有索引同名的任何类型的约束都会失败。

示例 38. 使用与现有索引同名的节点属性类型约束创建
使用名称 directors 创建索引
CREATE INDEX directors FOR (director:Director) ON (director.name)
使用名称 directors 创建节点属性类型约束
CREATE CONSTRAINT directors FOR (movie:Movie) REQUIRE movie.director IS :: STRING
错误信息
There already exists an index called 'directors'.

在与现有索引位于相同模式上创建键或属性唯一性约束将失败。

示例 39. 在与现有索引位于相同模式上创建节点属性唯一性约束
Book 节点上的 wordCount 属性创建索引
CREATE INDEX book_word_count FOR (book:Book) ON (book.wordCount)
创建一个约束,要求所有 Book 节点具有唯一的 wordCount 属性
CREATE CONSTRAINT word_count FOR (book:Book) REQUIRE book.wordCount IS UNIQUE
错误信息
There already exists an index (:Book {wordCount}).
A constraint cannot be created until the index has been dropped.

约束和数据违反场景

创建违反现有约束的数据将失败

表 1. 阻止数据创建的现有约束
约束类型 创建没有存在约束属性的节点和关系 创建具有非唯一属性/属性组合的节点和关系 创建具有错误属性类型的节点和关系

属性唯一性约束

属性存在约束

属性类型约束

键约束

示例 40. 创建违反节点属性唯一性约束的节点
创建一个具有已存在 isbn 属性的 Book 节点
CREATE (book:Book {isbn: '1449356265', title: 'Graph Databases'})
错误信息
Node(0) already exists with label `Book` and property `isbn` = '1449356265'
示例 41. 创建违反现有节点属性存在约束的节点
创建一个没有 name 属性的 Author 节点,假设在 :Author(name) 上存在属性存在约束
CREATE (author:Author {surname: 'Austen'})
错误信息
Node(0) with label `Author` must have the property `name`
示例 42. 创建违反现有关系属性类型约束的关系
创建一个具有 STRING order 属性的 PART_OF 关系,假设在关系类型 PART_OF 上存在一个属性类型约束,将 order 属性限制为 INTEGER
MATCH (movie:Movie {title:'Iron Man'}), (franchise:Franchise {name:'MCU'})
CREATE (movie)-[part:PART_OF {order: '1'}]->(franchise)
错误信息
Relationship(0) with type `PART_OF` has property `order` of wrong type `String`. Allowed types: INTEGER
示例 43. 创建违反现有节点键约束的节点
创建一个没有 firstname 属性的 Actor 节点,假设在 :Actor(firstname, surname) 上存在节点键约束
CREATE (actor:Actor {surname: 'Wood'})
错误信息
Node(0) with label `Actor` must have the properties (`firstname`, `surname`)

删除现有约束属性将失败

示例 44. 删除节点属性存在约束属性
从现有 Author 节点中删除 name 属性,假设在 :Author(name) 上存在属性存在约束
MATCH (author:Author {name: 'Virginia Woolf'})
REMOVE author.name
错误信息
Node(0) with label `Author` must have the property `name`
示例 45. 删除节点键约束属性
从现有节点 Actor 中删除 firstname 属性,假设在 :Actor(firstname, surname) 上存在节点键约束
MATCH (actor:Actor {firstname: 'Keanu', surname: 'Reeves'})
REMOVE actor.firstname
错误信息
Node(0) with label `Actor` must have the properties (`firstname`, `surname`)

修改类型约束属性将失败

示例 46. 修改类型约束属性
Movie 'Iron Man' 的 title 修改为 INTEGER 值,假设存在一个约束,要求 title 属性为 STRING 类型
MATCH (m:Movie {title: 'Iron Man'})
SET m.title = 13
错误信息
Node(9) with label `Movie` required the property `title` to be of type `STRING`, but was of type `INTEGER`.

在存在冲突数据的情况下创建约束将失败

表 2. 阻止创建约束的现有数据
约束类型 不存在的属性 不唯一的属性/属性组合 错误类型的属性

属性唯一性约束

属性存在约束

属性类型约束

键约束

示例 47. 在存在冲突节点的情况下创建节点属性唯一性约束
创建两个具有相同name属性值的Book节点
CREATE (:Book {isbn: '9780393972832', title: 'Moby Dick'}),
       (:Book {isbn: '9780763630188', title: 'Moby Dick'})
当已经存在两个具有相同titleBook节点时,创建要求Book节点具有唯一title属性的约束
CREATE CONSTRAINT book_title FOR (book:Book) REQUIRE book.title IS UNIQUE

在这种情况下,无法创建约束,因为它与现有图冲突。可以改用索引,或者删除/更正冲突节点,然后重新应用约束。

错误信息
Unable to create Constraint( name='book_title', type='UNIQUENESS', schema=(:Book {title}) ):
Both Node(0) and Node(1) have the label `Book` and property `title` = 'Moby Dick'

约束创建在找到的第一个冲突节点上失败。这不能保证图中没有其他冲突节点。因此,应该检查和清理所有数据,然后再尝试创建约束。

查找具有上述约束中不唯一属性值的全部冲突节点
MATCH (book1:Book), (book2:Book)
WHERE book1.title = book2.title AND NOT book1 = book2
RETURN book1, book2
示例 48. 在存在冲突关系的情况下创建关系属性存在约束
当已经存在一个没有language属性的WROTE关系时,创建要求所有WROTE关系具有language属性的约束
CREATE CONSTRAINT wrote_language FOR ()-[wrote:WROTE]-() REQUIRE wrote.language IS NOT NULL

在这种情况下,无法创建约束,因为它与现有图冲突。删除或更正冲突关系,然后重新应用约束。

错误信息
Unable to create Constraint( type='RELATIONSHIP PROPERTY EXISTENCE', schema=()-[:WROTE {language}]-() ):
Relationship(0) with type `WROTE` must have the property `language`. Note that only the first found violation is shown.

约束创建在找到的第一个冲突关系上失败。这不能保证图中没有其他冲突关系。因此,应该检查和清理所有数据,然后再尝试创建约束。

查找缺少上述约束中属性的全部冲突关系
MATCH ()-[wrote:WROTE]-()
WHERE wrote.language IS NULL
RETURN wrote
表 3. 用于查找阻止创建特定约束的属性的通用MATCH查询
约束 查询

节点属性唯一性约束

MATCH (n1:Label), (n2:Label)
WHERE n1.prop = n2.prop AND NOT n1 = n2
RETURN n1, n2

关系属性唯一性约束

MATCH ()-[r1:REL_TYPE]->(), ()-[r2:REL_TYPE]->()
WHERE r1.prop = r2.prop AND NOT r1 = r2
RETURN r1, r2

节点属性存在约束

MATCH (n:Label)
WHERE n.prop IS NULL
RETURN n

关系属性存在约束

MATCH ()-[r:REL_TYPE]->()
WHERE r.prop IS NULL
RETURN r

节点属性类型约束

MATCH (n:Label)
WHERE n.prop IS NOT :: <TYPE>
RETURN n

关系属性类型约束

MATCH ()-[r:REL_TYPE]->()
WHERE r.prop IS NOT :: <TYPE>
RETURN r

节点键约束

MATCH (n1:Label), (n2:Label)
WHERE n1.prop = n2.prop AND NOT n1 = n2
UNWIND [n1, n2] AS node
RETURN node, 'non-unique' AS reason
UNION
MATCH (n:Label)
WHERE n.prop IS NULL
RETURN n AS node, 'non-existing' AS reason

关系键约束

MATCH ()-[r1:REL_TYPE]->(), ()-[r2:REL_TYPE]->()
WHERE r1.prop = r2.prop AND NOT r1 = r2
UNWIND [r1, r2] AS relationship
RETURN relationship, 'non-unique' AS reason
UNION
MATCH ()-[r:REL_TYPE]->()
WHERE r.prop IS NULL
RETURN r AS relationship, 'non-existing' AS reason

SHOW CONSTRAINTS

要列出所有具有默认输出列的约束,请使用SHOW CONSTRAINTS。如果需要所有列,请使用SHOW CONSTRAINTS YIELD *。有关列出约束的完整命令语法,请参见语法 → SHOW CONSTRAINTS.

SHOW CONSTRAINTS的输出列之一是约束的名称。这可以用于使用DROP CONSTRAINT命令删除约束。

列出约束需要SHOW CONSTRAINTS权限.
示例 49. 列出所有具有默认输出列的约束
查询
SHOW CONSTRAINTS
结果
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                          | type                              | entityType     | labelsOrTypes  | properties                         | ownedIndex                    | propertyType                     |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 21 | "actor_fullname"              | "NODE_KEY"                        | "NODE"         | ["Actor"]      | ["firstname", "surname"]           | "actor_fullname"              | NULL                             |
| 10 | "author_name"                 | "NODE_PROPERTY_EXISTENCE"         | "NODE"         | ["Author"]     | ["name"]                           | NULL                          | NULL                             |
| 3  | "book_isbn"                   | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["isbn"]                           | "book_isbn"                   | NULL                             |
| 7  | "book_title_year"             | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["title", "publicationYear"]       | "book_title_year"             | NULL                             |
| 28 | "constraint_with_provider"    | "NODE_KEY"                        | "NODE"         | ["Actor"]      | ["surname"]                        | "constraint_with_provider"    | NULL                             |
| 17 | "director_imdbId"             | "NODE_KEY"                        | "NODE"         | ["Director"]   | ["imdbId"]                         | "director_imdbId"             | NULL                             |
| 23 | "knows_since_how"             | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["KNOWS"]      | ["since", "how"]                   | "knows_since_how"             | NULL                             |
| 14 | "movie_tagline"               | "NODE_PROPERTY_TYPE"              | "NODE"         | ["Movie"]      | ["tagline"]                        | NULL                          | "STRING | LIST<STRING NOT NULL>" |
| 12 | "movie_title"                 | "NODE_PROPERTY_TYPE"              | "NODE"         | ["Movie"]      | ["title"]                          | NULL                          | "STRING"                         |
| 25 | "node_uniqueness_param"       | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["prop1"]                          | "node_uniqueness_param"       | NULL                             |
| 19 | "ownershipId"                 | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["OWNS"]       | ["ownershipId"]                    | "ownershipId"                 | NULL                             |
| 13 | "part_of"                     | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["order"]                          | NULL                          | "INTEGER"                        |
| 15 | "part_of_tags"                | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["tags"]                           | NULL                          | "STRING | LIST<STRING NOT NULL>" |
| 9  | "prequels"                    | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"]                | "prequels"                    | NULL                             |
| 30 | "rel_constraint_with_options" | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order", "seriesTitle", "number"] | "rel_constraint_with_options" | NULL                             |
| 26 | "rel_exist_param"             | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["published"]                      | NULL                          | NULL                             |
| 5  | "sequels"                     | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order"]                          | "sequels"                     | NULL                             |
| 11 | "wrote_year"                  | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["year"]                           | NULL                          | NULL                             |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例 50. 列出所有具有完整详细信息的约束

要返回数据库上约束的完整详细信息,请使用SHOW CONSTRAINTS YIELD *

使用YIELD *列出所有约束
SHOW CONSTRAINTS YIELD *
结果
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                          | type                              | entityType     | labelsOrTypes  | properties                         | ownedIndex                    | propertyType                     | options                                       | createStatement                                                                                                                        |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 21 | "actor_fullname"              | "NODE_KEY"                        | "NODE"         | ["Actor"]      | ["firstname", "surname"]           | "actor_fullname"              | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `actor_fullname` FOR (n:`Actor`) REQUIRE (n.`firstname`, n.`surname`) IS NODE KEY"                                  |
| 10 | "author_name"                 | "NODE_PROPERTY_EXISTENCE"         | "NODE"         | ["Author"]     | ["name"]                           | NULL                          | NULL                             | NULL                                          | "CREATE CONSTRAINT `author_name` FOR (n:`Author`) REQUIRE (n.`name`) IS NOT NULL"                                                      |
| 3  | "book_isbn"                   | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["isbn"]                           | "book_isbn"                   | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `book_isbn` FOR (n:`Book`) REQUIRE (n.`isbn`) IS UNIQUE"                                                            |
| 7  | "book_title_year"             | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["title", "publicationYear"]       | "book_title_year"             | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `book_title_year` FOR (n:`Book`) REQUIRE (n.`title`, n.`publicationYear`) IS UNIQUE"                                |
| 28 | "constraint_with_provider"    | "NODE_KEY"                        | "NODE"         | ["Actor"]      | ["surname"]                        | "constraint_with_provider"    | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `constraint_with_provider` FOR (n:`Actor`) REQUIRE (n.`surname`) IS NODE KEY"                                       |
| 17 | "director_imdbId"             | "NODE_KEY"                        | "NODE"         | ["Director"]   | ["imdbId"]                         | "director_imdbId"             | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `director_imdbId` FOR (n:`Director`) REQUIRE (n.`imdbId`) IS NODE KEY"                                              |
| 23 | "knows_since_how"             | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["KNOWS"]      | ["since", "how"]                   | "knows_since_how"             | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `knows_since_how` FOR ()-[r:`KNOWS`]-() REQUIRE (r.`since`, r.`how`) IS RELATIONSHIP KEY"                           |
| 14 | "movie_tagline"               | "NODE_PROPERTY_TYPE"              | "NODE"         | ["Movie"]      | ["tagline"]                        | NULL                          | "STRING | LIST<STRING NOT NULL>" | NULL                                          | "CREATE CONSTRAINT `movie_tagline` FOR (n:`Movie`) REQUIRE (n.`tagline`) IS :: STRING | LIST<STRING NOT NULL>"                         |
| 12 | "movie_title"                 | "NODE_PROPERTY_TYPE"              | "NODE"         | ["Movie"]      | ["title"]                          | NULL                          | "STRING"                         | NULL                                          | "CREATE CONSTRAINT `movie_title` FOR (n:`Movie`) REQUIRE (n.`title`) IS :: STRING"                                                     |
| 25 | "node_uniqueness_param"       | "UNIQUENESS"                      | "NODE"         | ["Book"]       | ["prop1"]                          | "node_uniqueness_param"       | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `node_uniqueness_param` FOR (n:`Book`) REQUIRE (n.`prop1`) IS UNIQUE"                                               |
| 19 | "ownershipId"                 | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["OWNS"]       | ["ownershipId"]                    | "ownershipId"                 | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `ownershipId` FOR ()-[r:`OWNS`]-() REQUIRE (r.`ownershipId`) IS RELATIONSHIP KEY"                                   |
| 13 | "part_of"                     | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["order"]                          | NULL                          | "INTEGER"                        | NULL                                          | "CREATE CONSTRAINT `part_of` FOR ()-[r:`PART_OF`]-() REQUIRE (r.`order`) IS :: INTEGER"                                                |
| 15 | "part_of_tags"                | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["tags"]                           | NULL                          | "STRING | LIST<STRING NOT NULL>" | NULL                                          | "CREATE CONSTRAINT `part_of_tags` FOR ()-[r:`PART_OF`]-() REQUIRE (r.`tags`) IS :: STRING | LIST<STRING NOT NULL>"                     |
| 9  | "prequels"                    | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"]                | "prequels"                    | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `prequels` FOR ()-[r:`PREQUEL_OF`]-() REQUIRE (r.`order`, r.`author`) IS UNIQUE"                                    |
| 30 | "rel_constraint_with_options" | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order", "seriesTitle", "number"] | "rel_constraint_with_options" | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `rel_constraint_with_options` FOR ()-[r:`SEQUEL_OF`]-() REQUIRE (r.`order`, r.`seriesTitle`, r.`number`) IS UNIQUE" |
| 26 | "rel_exist_param"             | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["published"]                      | NULL                          | NULL                             | NULL                                          | "CREATE CONSTRAINT `rel_exist_param` FOR ()-[r:`WROTE`]-() REQUIRE (r.`published`) IS NOT NULL"                                        |
| 5  | "sequels"                     | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order"]                          | "sequels"                     | NULL                             | {indexConfig: {}, indexProvider: "range-1.0"} | "CREATE CONSTRAINT `sequels` FOR ()-[r:`SEQUEL_OF`]-() REQUIRE (r.`order`) IS UNIQUE"                                                  |
| 11 | "wrote_year"                  | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["year"]                           | NULL                          | NULL                             | NULL                                          | "CREATE CONSTRAINT `wrote_year` FOR ()-[r:`WROTE`]-() REQUIRE (r.`year`) IS NOT NULL"                                                  |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
type列对于节点属性唯一性约束返回UNIQUENESS,对于关系属性唯一性约束返回RELATIONSHIP_UNIQUENESS。这将在 Neo4j 的未来版本中更新。节点属性唯一性约束将更新为NODE_PROPERTY_UNIQUENESS,关系属性唯一性约束将更新为RELATIONSHIP_PROPERTY_UNIQUENESS

使用过滤列出约束

SHOW CONSTRAINTS命令可以用多种方式进行过滤。可以使用约束类型关键字或WHERE子句过滤行,而使用YIELD子句指定所需的列来过滤列。

示例 51. 仅列出特定的约束类型
仅列出键约束
SHOW KEY CONSTRAINTS
结果
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                       | type               | entityType     | labelsOrTypes | properties               | ownedIndex                 | propertyType |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 21 | "actor_fullname"           | "NODE_KEY"         | "NODE"         | ["Actor"]     | ["firstname", "surname"] | "actor_fullname"           | NULL         |
| 28 | "constraint_with_provider" | "NODE_KEY"         | "NODE"         | ["Actor"]     | ["surname"]              | "constraint_with_provider" | NULL         |
| 17 | "director_imdbId"          | "NODE_KEY"         | "NODE"         | ["Director"]  | ["imdbId"]               | "director_imdbId"          | NULL         |
| 23 | "knows_since_how"          | "RELATIONSHIP_KEY" | "RELATIONSHIP" | ["KNOWS"]     | ["since", "how"]         | "knows_since_how"          | NULL         |
| 19 | "ownershipId"              | "RELATIONSHIP_KEY" | "RELATIONSHIP" | ["OWNS"]      | ["ownershipId"]          | "ownershipId"              | NULL         |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+

有关此命令中所有可用约束类型(和同义词)的完整列表,请参见语法 → SHOW CONSTRAINTS.

示例 52. 使用WHERE子句过滤约束
仅列出具有RELATIONSHIP entityType的约束
SHOW CONSTRAINTS
WHERE entityType = 'RELATIONSHIP'
结果
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | name                          | type                              | entityType     | labelsOrTypes  | properties                         | ownedIndex                    | propertyType                     |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 23 | "knows_since_how"             | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["KNOWS"]      | ["since", "how"]                   | "knows_since_how"             | NULL                             |
| 19 | "ownershipId"                 | "RELATIONSHIP_KEY"                | "RELATIONSHIP" | ["OWNS"]       | ["ownershipId"]                    | "ownershipId"                 | NULL                             |
| 13 | "part_of"                     | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["order"]                          | NULL                          | "INTEGER"                        |
| 15 | "part_of_tags"                | "RELATIONSHIP_PROPERTY_TYPE"      | "RELATIONSHIP" | ["PART_OF"]    | ["tags"]                           | NULL                          | "STRING | LIST<STRING NOT NULL>" |
| 9  | "prequels"                    | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"]                | "prequels"                    | NULL                             |
| 30 | "rel_constraint_with_options" | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order", "seriesTitle", "number"] | "rel_constraint_with_options" | NULL                             |
| 26 | "rel_exist_param"             | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["published"]                      | NULL                          | NULL                             |
| 5  | "sequels"                     | "RELATIONSHIP_UNIQUENESS"         | "RELATIONSHIP" | ["SEQUEL_OF"]  | ["order"]                          | "sequels"                     | NULL                             |
| 11 | "wrote_year"                  | "RELATIONSHIP_PROPERTY_EXISTENCE" | "RELATIONSHIP" | ["WROTE"]      | ["year"]                           | NULL                          | NULL                             |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例 53. 返回所有约束的特定列

可以使用YIELD子句仅返回可用约束的特定列

仅列出nametypecreateStatement
SHOW CONSTRAINTS
YIELD name, type, createStatement
结果
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name                          | type                              | createStatement                                                                                                                        |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "actor_fullname"              | "NODE_KEY"                        | "CREATE CONSTRAINT `actor_fullname` FOR (n:`Actor`) REQUIRE (n.`firstname`, n.`surname`) IS NODE KEY"                                  |
| "author_name"                 | "NODE_PROPERTY_EXISTENCE"         | "CREATE CONSTRAINT `author_name` FOR (n:`Author`) REQUIRE (n.`name`) IS NOT NULL"                                                      |
| "book_isbn"                   | "UNIQUENESS"                      | "CREATE CONSTRAINT `book_isbn` FOR (n:`Book`) REQUIRE (n.`isbn`) IS UNIQUE"                                                            |
| "book_title_year"             | "UNIQUENESS"                      | "CREATE CONSTRAINT `book_title_year` FOR (n:`Book`) REQUIRE (n.`title`, n.`publicationYear`) IS UNIQUE"                                |
| "constraint_with_provider"    | "NODE_KEY"                        | "CREATE CONSTRAINT `constraint_with_provider` FOR (n:`Actor`) REQUIRE (n.`surname`) IS NODE KEY"                                       |
| "director_imdbId"             | "NODE_KEY"                        | "CREATE CONSTRAINT `director_imdbId` FOR (n:`Director`) REQUIRE (n.`imdbId`) IS NODE KEY"                                              |
| "knows_since_how"             | "RELATIONSHIP_KEY"                | "CREATE CONSTRAINT `knows_since_how` FOR ()-[r:`KNOWS`]-() REQUIRE (r.`since`, r.`how`) IS RELATIONSHIP KEY"                           |
| "movie_tagline"               | "NODE_PROPERTY_TYPE"              | "CREATE CONSTRAINT `movie_tagline` FOR (n:`Movie`) REQUIRE (n.`tagline`) IS :: STRING | LIST<STRING NOT NULL>"                         |
| "movie_title"                 | "NODE_PROPERTY_TYPE"              | "CREATE CONSTRAINT `movie_title` FOR (n:`Movie`) REQUIRE (n.`title`) IS :: STRING"                                                     |
| "node_uniqueness_param"       | "UNIQUENESS"                      | "CREATE CONSTRAINT `node_uniqueness_param` FOR (n:`Book`) REQUIRE (n.`prop1`) IS UNIQUE"                                               |
| "ownershipId"                 | "RELATIONSHIP_KEY"                | "CREATE CONSTRAINT `ownershipId` FOR ()-[r:`OWNS`]-() REQUIRE (r.`ownershipId`) IS RELATIONSHIP KEY"                                   |
| "part_of"                     | "RELATIONSHIP_PROPERTY_TYPE"      | "CREATE CONSTRAINT `part_of` FOR ()-[r:`PART_OF`]-() REQUIRE (r.`order`) IS :: INTEGER"                                                |
| "part_of_tags"                | "RELATIONSHIP_PROPERTY_TYPE"      | "CREATE CONSTRAINT `part_of_tags` FOR ()-[r:`PART_OF`]-() REQUIRE (r.`tags`) IS :: STRING | LIST<STRING NOT NULL>"                     |
| "prequels"                    | "RELATIONSHIP_UNIQUENESS"         | "CREATE CONSTRAINT `prequels` FOR ()-[r:`PREQUEL_OF`]-() REQUIRE (r.`order`, r.`author`) IS UNIQUE"                                    |
| "rel_constraint_with_options" | "RELATIONSHIP_UNIQUENESS"         | "CREATE CONSTRAINT `rel_constraint_with_options` FOR ()-[r:`SEQUEL_OF`]-() REQUIRE (r.`order`, r.`seriesTitle`, r.`number`) IS UNIQUE" |
| "rel_exist_param"             | "RELATIONSHIP_PROPERTY_EXISTENCE" | "CREATE CONSTRAINT `rel_exist_param` FOR ()-[r:`WROTE`]-() REQUIRE (r.`published`) IS NOT NULL"                                        |
| "sequels"                     | "RELATIONSHIP_UNIQUENESS"         | "CREATE CONSTRAINT `sequels` FOR ()-[r:`SEQUEL_OF`]-() REQUIRE (r.`order`) IS UNIQUE"                                                  |
| "wrote_year"                  | "RELATIONSHIP_PROPERTY_EXISTENCE" | "CREATE CONSTRAINT `wrote_year` FOR ()-[r:`WROTE`]-() REQUIRE (r.`year`) IS NOT NULL"                                                  |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

列出约束的结果列

表 4. 列出约束输出
描述 类型

id

约束的 ID。默认输出

INTEGER

name

约束的名称(由用户显式设置或自动分配)。默认输出

STRING

type

此约束的 ConstraintType(UNIQUENESS(节点唯一性)、RELATIONSHIP_UNIQUENESSNODE_PROPERTY_EXISTENCERELATIONSHIP_PROPERTY_EXISTENCENODE_PROPERTY_TYPERELATIONSHIP_PROPERTY_TYPENODE_KEYRELATIONSHIP_KEY)。默认输出

UNIQUENESSRELATIONSHIP_UNIQUENESS将在 Neo4j 的未来版本中分别更新为NODE_PROPERTY_UNIQUENESSRELATIONSHIP_PROPERTY_UNIQUENESS

STRING

entityType

此约束表示的实体类型(NODERELATIONSHIP)。默认输出

STRING

labelsOrTypes

此约束的标签或关系类型。返回的列表将只包含一个值(受约束的节点标签或关系类型的名称)。默认输出

LIST<STRING>

properties

此约束的属性。默认输出

LIST<STRING>

ownedIndex

与约束关联的索引的名称,或者在没有关联索引的情况下为null默认输出

STRING

propertyType

对于属性类型约束,属性被限制为的属性类型,对于其他约束则为null默认输出 在 5.9 中引入

STRING

options

传递给CREATE命令的选项,用于与约束关联的索引,或者在没有与约束关联索引的情况下为null

MAP

createStatement

用于创建约束的语句。

STRING

DROP CONSTRAINT

使用DROP CONSTRAINT命令删除约束。有关删除约束的完整命令语法,请参见语法 → DROP CONSTRAINT.

删除约束需要DROP CONSTRAINT权限.

按名称删除约束

可以使用DROP CONSTRAINT constraint_name命令使用名称删除约束。对于所有约束类型,命令都是相同的。可以使用SHOW CONSTRAINTS命令找到约束的名称,该名称在输出列name中给出。

示例 54. 按名称删除约束
删除约束book_isbn
DROP CONSTRAINT book_isbn
结果
Removed 1 constraint.

使用参数删除约束

可以使用参数化名称删除约束。

示例 55. 使用参数删除约束
参数
{
  "name": "actor_fullname"
}
使用参数化名称删除约束
DROP CONSTRAINT $name
结果
Removed 1 constraint.

删除不存在的约束

如果不确定是否存在具有给定名称的约束,并且希望在存在的情况下删除它,但如果不存在则不希望出现错误,请使用IF EXISTS。这将确保不会抛出错误。从 Neo4j 5.17 开始,将返回一条信息通知,说明约束不存在。

示例 56. 删除不存在的约束
删除不存在的约束missing_constraint_name
DROP CONSTRAINT missing_constraint_name IF EXISTS
结果
(no changes, no records)
通知
`DROP CONSTRAINT missing_constraint_name IF EXISTS` has no effect. `missing_constraint_name` does not exist.