创建约束
使用 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。
有关创建属性唯一性约束的完整命令语法,请参阅 语法 → 创建属性唯一性约束。
Book 节点必须具有唯一的 isbn 属性CREATE CONSTRAINT book_isbn
FOR (book:Book) REQUIRE book.isbn IS UNIQUE
Added 1 constraint.
SEQUEL_OF 关系必须具有唯一的 order 属性CREATE CONSTRAINT sequels
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE
Added 1 constraint.
创建复合属性唯一性约束
为多个属性创建的约束称为复合约束。请注意,在创建复合属性唯一性约束时,必须将受约束的属性括在括号内。
-
节点属性唯一性约束:
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。
有关创建属性唯一性约束的完整命令语法,请参阅 语法 → 创建属性唯一性约束。
Book 节点必须具有唯一的 title 和 publicationYear 属性组合CREATE CONSTRAINT book_title_year
FOR (book:Book) REQUIRE (book.title, book.publicationYear) IS UNIQUE
Added 1 constraint.
PREQUEL_OF 关系必须具有唯一的 order 和 author 属性组合CREATE CONSTRAINT prequels
FOR ()-[prequel:PREQUEL_OF]-() REQUIRE (prequel.order, prequel.author) IS UNIQUE
Added 1 constraint.
创建符合现有属性唯一性约束的数据
isbn 属性的 Book 节点CREATE (book:Book {isbn: '1449356265', title: 'Graph Databases'})
Added 1 label, created 1 node, set 2 properties
order 属性的 SEQUEL_OF 关系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。
有关创建存在性约束的完整命令语法,请参阅 语法 → 创建属性存在性约束。
| 无法在多个属性上创建复合存在性约束。 |
Author 节点必须具有 name 属性CREATE CONSTRAINT author_name
FOR (author:Author) REQUIRE author.name IS NOT NULL
Added 1 constraint.
WROTE 关系必须具有 year 属性CREATE CONSTRAINT wrote_year
FOR ()-[wrote:WROTE]-() REQUIRE wrote.year IS NOT NULL
Added 1 constraint.
创建符合现有属性存在性约束的数据
name 属性的 Author 节点CREATE (author:Author {name:'Virginia Woolf', surname: 'Woolf'})
Added 1 label, created 1 node, set 2 properties
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® 数据类型,例如 STRING 或 INTEGER。有关属性可受约束的类型,请参阅 允许的类型;有关 Cypher 中不同数据类型的信息,请参阅 值和类型。有关创建属性类型约束的完整命令语法,请参阅 语法 → 创建属性类型约束。
| 无法在多个属性上创建复合属性类型约束。 |
Movie 节点上的 title 属性必须为 STRING 类型CREATE CONSTRAINT movie_title
FOR (movie:Movie) REQUIRE movie.title IS :: STRING
Added 1 constraint.
PART_OF 关系上的 order 属性必须为 INTEGER 类型CREATE CONSTRAINT part_of
FOR ()-[part:PART_OF]-() REQUIRE part.order IS :: INTEGER
Added 1 constraint.
VECTOR 属性类型约束 仅限 Cypher 25 引入于 Neo4j 2025.10必须为任何受约束的 VECTOR 属性指定维度和坐标类型。维度必须大于 0 且小于等于 4096。有关更多信息,请参阅 值和类型 → 向量。
Movie 节点上的 embedding 属性必须为 VECTOR<INT32>(42) 类型CREATE CONSTRAINT node_vector_constraint
FOR (n:Movie) REQUIRE n.embedding IS :: VECTOR<INT32>(42)
Added 1 constraint.
CONTAINS 关系上的 embedding 属性必须为 VECTOR<FLOAT32>(1536) 类型CREATE CONSTRAINT rel_vector_constraint
FOR ()-[r:CONTAINS]->() REQUIRE r.embedding IS :: VECTOR<FLOAT32>(1536)
Added 1 constraint.
创建联合类型的属性类型约束
闭合动态联合类型允许节点或关系属性保持一定的类型灵活性,同时防止存储意外的值。
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.
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 -
VECTOR<TYPE>(DIMENSION)仅限 Cypher 25 引入于 Neo4j 2025.10 -
LIST<BOOLEAN NOT NULL> -
LIST<STRING NOT NULL> -
LIST<INTEGER NOT NULL> -
LIST<FLOAT NOT NULL> -
LIST<DATE NOT NULL> -
LIST<LOCAL TIME NOT NULL> -
LIST<ZONED TIME NOT NULL> -
LIST<LOCAL DATETIME NOT NULL> -
LIST<ZONED DATETIME NOT NULL> -
LIST<DURATION NOT NULL> -
LIST<POINT NOT NULL> -
上述类型的任何闭合动态联合,例如
INTEGER | FLOAT | STRING。
由于不支持存储 VECTOR 值列表,因此无法为 LIST<VECTOR<TYPE>(DIMENSION) NOT NULL> 创建属性类型约束。此外,VECTOR 属性类型约束必须使用特定的维度和坐标值创建,其中维度必须大于 0 且小于等于 4096。有关更多信息,请参阅 值和类型 → 向量。 |
有关描述 Cypher 中所有可用类型的完整参考,请参阅关于 类型及其同义词 的部分。
创建符合现有属性类型约束的数据
STRING 类型 title 属性的 Movie 节点CREATE (movie:Movie {title:'Iron Man'})
Added 1 label, created 1 node, set 1 properties
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。
有关创建键约束的完整命令语法,请参阅 语法 → 创建键约束。
Director 节点必须具有唯一的 imdbId 属性作为节点键。CREATE CONSTRAINT director_imdbId
FOR (director:Director) REQUIRE (director.imdbId) IS NODE KEY
Added 1 constraint.
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。
有关创建键约束的完整命令语法,请参阅 语法 → 创建键约束。
Actor 节点必须具有唯一的 firstname 和 surname 属性组合作为节点键CREATE CONSTRAINT actor_fullname
FOR (actor:Actor) REQUIRE (actor.firstname, actor.surname) IS NODE KEY
Added 1 constraint.
KNOWS 关系必须具有唯一的 since 和 how 属性组合作为关系键CREATE CONSTRAINT knows_since_how
FOR ()-[knows:KNOWS]-() REQUIRE (knows.since, knows.how) IS RELATIONSHIP KEY
Added 1 constraint.
创建符合现有键约束的数据
firstname 和 surname 属性的 Actor 节点CREATE (actor:Actor {firstname: 'Keanu', surname: 'Reeves'})
Added 1 label, created 1 node, set 2 properties.
since 和 how 属性的 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.
使用参数创建约束
所有约束类型都可以使用参数化名称进行创建。
{
"name": "node_uniqueness_param"
}
CREATE CONSTRAINT $name
FOR (book:Book) REQUIRE book.prop1 IS UNIQUE
Added 1 constraint.
{
"name": "rel_exist_param"
}
CREATE CONSTRAINT $name
FOR ()-[wrote:WROTE]-() REQUIRE wrote.published IS NOT NULL
Added 1 constraint.
处理多个约束
创建已经存在的约束将会失败。这包括以下情况:
-
创建与现有约束完全相同的约束。
-
创建名称不同,但与现有约束属于同一约束类型、作用于相同标签/关系类型且属性组合也相同的约束。对于属性类型约束,属性类型也必须相同。
-
创建名称与现有约束相同(无论该现有约束是什么类型)的约束。
此外,某些约束不能共存,因此尝试同时创建它们也会失败。这包括:
-
在相同标签/关系类型和属性上存在具有不同类型的属性类型约束。这包括具有不同维度或坐标类型的
VECTOR类型。 -
在相同标签/关系类型和属性组合上同时存在属性唯一性约束和键约束。
但是,某些约束类型在相同标签/关系类型和属性组合上是允许的。例如,可以同时在相同标签/关系类型和属性组合上拥有属性唯一性约束和属性存在性约束,但这相当于拥有了一个节点或关系键约束。更有用的例子是结合属性类型约束和属性存在性约束,以确保该属性既存在又具有指定的类型。
创建约束时处理现有约束
为了避免因现有约束而失败,可以在 CREATE 命令中添加 IF NOT EXISTS。这可以确保如果存在具有给定名称的约束,或者在相同约束类型和模式上存在另一个约束,则不会抛出错误,也不会创建新约束。对于属性类型约束,属性类型也必须相同。相反,系统将返回一个信息性通知,显示阻止创建的现有约束。
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.
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.
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.
创建已经存在的约束将会失败
如果创建的约束名称相同,或者在相同节点标签或关系类型以及已被相同类型约束的属性上创建约束,将会失败。属性唯一性约束和键约束也不允许在相同的模式上同时存在。
SEQUEL_OF 关系具有唯一 order 属性的约束CREATE CONSTRAINT sequels
FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE
22N65: 错误: 数据异常 - 等效约束已存在。等效约束已存在:'sequels' |
Book 节点具有唯一 isbn 属性的约束CREATE CONSTRAINT new_book_isbn
FOR (book:Book) REQUIRE book.isbn IS UNIQUE
22N65: 错误: 数据异常 - 等效约束已存在。等效约束已存在:'Constraint( id=3, name='book_isbn', type='NODE PROPERTY UNIQUENESS', schema=(:Book {isbn}), ownedIndex=2 )' |
AUTHORED 关系具有唯一 name 属性的约束CREATE CONSTRAINT author_name
FOR ()-[a:AUTHORED]-() REQUIRE a.name IS UNIQUE
22N67: 错误: 数据异常 - 约束名称重复。名称相同的约束已存在: |
PART_OF 关系上的 order 属性为 INTEGER 类型的约束的情况下,创建一个要求该属性为 FLOAT 类型的约束CREATE CONSTRAINT new_part_of
FOR ()-[part:PART_OF]-() REQUIRE part.order IS :: FLOAT
22N66: 错误: 数据异常 - 冲突约束已存在。冲突约束已存在:'Constraint( id=13, name='part_of', type='RELATIONSHIP PROPERTY TYPE', schema=()-[:PART_OF {order}]-(), propertyType=INTEGER )' |
Book 标签节点上的 title 和 publicationYear 属性创建节点键约束CREATE CONSTRAINT book_titles FOR (book:Book) REQUIRE (book.title, book.publicationYear) IS NODE KEY
22N66: 错误: 数据异常 - 冲突约束已存在。冲突约束已存在:'Constraint( id=7, name='book_title_year', type='NODE PROPERTY UNIQUENESS', schema=(:Book {title, publicationYear}), ownedIndex=6 )' |
约束与索引
约束与底层索引
属性唯一性约束和键约束由 范围索引 (range indexes) 提供支持。这意味着创建属性唯一性约束或键约束时,会创建一个与该约束同名、具有相同节点标签/关系类型和属性组合的范围索引。单个属性约束将创建单个属性索引,多个属性的复合约束将创建 复合索引。
| 具有相同索引类型、标签/关系类型和属性组合的索引不能单独添加。但是,删除属性唯一性约束或键约束也会同时删除其支持索引。如果该支持索引仍有必要,则需要显式重新创建。 |
属性唯一性约束和键约束需要索引,因为它允许系统快速检查是否已存在具有相同标签和属性值(或相同类型和属性值)的节点或关系。没有索引,系统将需要扫描所有具有相同标签的节点,这在图规模增大时会非常缓慢且低效。索引通过支持直接查找而非全图扫描,使这些检查变得快得多。Cypher 将使用拥有约束的索引,方式与利用其他搜索性能索引相同。有关索引如何影响查询性能的更多信息,请参阅 索引对查询性能的影响。
这些索引列在 SHOW INDEX 命令返回的 owningConstraint 列中,以及 SHOW CONSTRAINT 命令返回的 ownedIndex 列中。
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" | "NODE_PROPERTY_UNIQUENESS" | "NODE" | ["Book"] | ["isbn"] | "book_isbn" | NULL |
| 7 | "book_title_year" | "NODE_PROPERTY_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" | "NODE_PROPERTY_UNIQUENESS" | "NODE" | ["Book"] | ["prop1"] | "node_uniqueness_param" | NULL |
| 19 | "ownershipId" | "RELATIONSHIP_KEY" | "RELATIONSHIP" | ["OWNS"] | ["ownershipId"] | "ownershipId" | NULL |
| 9 | "prequels" | "RELATIONSHIP_PROPERTY_UNIQUENESS" | "RELATIONSHIP" | ["PREQUEL_OF"] | ["order", "author"] | "prequels" | NULL |
| 5 | "sequels" | "RELATIONSHIP_PROPERTY_UNIQUENESS" | "RELATIONSHIP" | ["SEQUEL_OF"] | ["order"] | "sequels" | NULL |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
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 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 属性存在性约束和属性类型约束不由索引支持。 |
约束失败与索引
尝试创建与现有索引同名的任何类型的约束都会失败。
directors 的索引CREATE INDEX directors FOR (director:Director) ON (director.name)
directors 的节点属性类型约束CREATE CONSTRAINT directors FOR (movie:Movie) REQUIRE movie.director IS :: STRING
22N71: 错误: 数据异常 - 索引名称重复。同名索引已存在: |
在已有索引的模式上创建键约束或属性唯一性约束将会失败。
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
22N73: 错误: 数据异常 - 约束与现有索引冲突。约束与已存在的索引 '(:Book {wordCount})' 冲突。 |
约束与数据违规场景
创建违反现有约束的数据将会失败
| 约束类型 | 创建没有存在性约束属性的节点和关系 | 创建具有非唯一属性/属性组合的节点和关系 | 创建属性类型错误的节点和关系 |
|---|---|---|---|
属性唯一性约束 |
❌ |
||
属性存在性约束 |
❌ |
||
属性类型约束 |
❌ |
||
键约束 |
❌ |
❌ |
:Author(name) 存在性约束的情况下,创建一个没有 name 属性的 Author 节点CREATE (author:Author {surname: 'Austen'})
22N77: 错误: 数据异常 - 属性存在性验证失败。带有标签 'Author' 的节点 (11) 必须具有以下属性: |
order 属性为 INTEGER 类型的 PART_OF 关系属性类型约束的情况下,创建一个具有 STRING 类型 order 属性的 PART_OF 关系MATCH (movie:Movie {title:'Iron Man'}), (franchise:Franchise {name:'MCU'})
CREATE (movie)-[part:PART_OF {order: '1'}]->(franchise)
22N78: 错误: 数据异常 - 属性类型验证失败。类型为 'PART_OF' 的关系 (1155176602955415558) 必须具有属性 |
:Actor(firstname, surname) 节点键约束的情况下,创建一个没有 firstname 属性的 Actor 节点CREATE (actor:Actor {surname: 'Wood'})
22N77: 错误: 数据异常 - 属性存在性验证失败。带有标签 'Actor' 的节点 (11) 必须具有以下属性: |
删除受存在性约束和键约束的属性将会失败
:Author(name) 存在性约束的情况下,从现有的 Author 节点中删除 name 属性MATCH (author:Author {name: 'Virginia Woolf'})
REMOVE author.name
22N77: 错误: 数据异常 - 属性存在性验证失败。带有标签 'Author' 的节点 (3) 必须具有以下属性: |
:Actor(firstname, surname) 节点键约束的情况下,从现有的 Actor 节点中删除 firstname 属性MATCH (actor:Actor {firstname: 'Keanu', surname: 'Reeves'})
REMOVE actor.firstname
22N77: 错误: 数据异常 - 属性存在性验证失败。带有标签 'Actor' 的节点 (8) 必须具有以下属性: |
修改受类型约束的属性将会失败
title 属性为 STRING 类型的约束的情况下,将 Movie 'Iron Man' 的 title 修改为 INTEGER 值MATCH (m:Movie {title: 'Iron Man'})
SET m.title = 13
22N78: 错误: 数据异常 - 属性类型验证失败。带有标签 'Movie' 的节点 (6) 必须具有属性 |
在存在冲突数据的情况下创建约束将会失败
| 约束类型 | 不存在属性 | 非唯一属性/属性组合 | 属性类型错误 |
|---|---|---|---|
属性唯一性约束 |
❌ |
||
属性存在性约束 |
❌ |
||
属性类型约束 |
❌ |
||
键约束 |
❌ |
❌ |
name 属性值相同的 Book 节点CREATE (:Book {isbn: '9780393972832', title: 'Moby Dick'}),
(:Book {isbn: '9780763630188', title: 'Moby Dick'})
title 相同的 Book 节点的情况下,创建一个要求 Book 节点具有唯一 title 属性的约束CREATE CONSTRAINT book_title FOR (book:Book) REQUIRE book.title IS UNIQUE
在这种情况下,由于与现有图冲突,无法创建该约束。请改用 索引,或者删除/更正冲突节点,然后重新应用约束。
22N80: 错误: 数据异常 - 索引条目冲突。索引条目冲突:节点 (11) 和节点 (12) 都具有标签 22N79: 错误: 数据异常 - 违反属性唯一性约束。违反属性唯一性约束:节点 (11) 和节点 (12) 都具有标签 50N11: 错误: 一般处理异常 - 约束创建失败。无法创建 'book_title'。 |
约束创建在发现第一个冲突节点时就会失败。这并不能保证图中没有其他冲突节点。因此,在重新尝试创建约束之前,应检查并清理所有数据。
MATCH (book1:Book), (book2:Book)
WHERE book1.title = book2.title AND NOT book1 = book2
RETURN book1, book2
language 属性的 WROTE 关系的情况下,创建一个要求所有 WROTE 关系具有 language 属性的约束CREATE CONSTRAINT wrote_language FOR ()-[wrote:WROTE]-() REQUIRE wrote.language IS NOT NULL
在这种情况下,由于与现有图冲突,无法创建该约束。删除或更正冲突关系,然后重新应用约束。
22N77: 错误: 数据异常 - 属性存在性验证失败。类型为 'WROTE' 的关系 (1152923703630102532) 必须具有以下属性: 50N11: 错误: 一般处理异常 - 约束创建失败。无法创建 'Constraint( type='RELATIONSHIP PROPERTY EXISTENCE', schema=()-[:WROTE {language}]-() )'。 |
约束创建在发现第一个冲突关系时就会失败。这并不能保证图中没有其他冲突关系。因此,在重新尝试创建约束之前,应检查并清理所有数据。
MATCH ()-[wrote:WROTE]-()
WHERE wrote.language IS NULL
RETURN wrote
| 约束 | 查询 |
|---|---|
节点属性唯一性约束 |
|
关系属性唯一性约束 |
|
节点属性存在性约束 |
|
关系属性存在性约束 |
|
节点属性类型约束 |
|
关系属性类型约束 |
|
节点键约束 |
|
关系键约束 |
|