设置图类型

图类型定义了数据库的模式,并通过命令 ALTER CURRENT GRAPH TYPE SET 进行设置。请注意,当设置图类型时,任何先前定义的图类型或约束都将被覆盖并替换。

图类型可包含:

前三类在 在空数据库上设置图类型 一节中讨论。最后一类在 在已填充数据的数据库上设置图类型 一节中讨论。

设置图类型需要以下权限:

选择数据模型

在设置图类型之前,制定图的数据模型至关重要,因为图类型的作用是强制执行从该数据模型导出的模式。

在 Neo4j 中建模数据对于使用节点、关系和属性来表示复杂、互联的关系至关重要。与传统数据库不同,其图结构反映了现实世界的连接,使得遍历和查询变得更容易(有关数据建模的更多信息,请参阅 入门指南 → 数据建模)。

本页中的示例从一个识别人员、宠物及其居住城市的数据模型开始。定义了关键实体及其属性,包括人、宠物和城市的名字。人员和宠物都被归类为居民,数据模型捕捉了两者在特定城市居住的时长。

在空数据库上设置图类型

所有数据库在创建时都具有一个空的图类型。由于如果数据库中已有预存数据,设置图类型的过程可能会更复杂,因此建议在用数据填充图之前设置所需的图类型。

设置图类型以确保数据库中数据模型的完整性
ALTER CURRENT GRAPH TYPE SET {
    (:Person => :Resident {name :: STRING NOT NULL}),
    (:Pet => :Resident&Animal {healthCertificate :: STRING, name :: STRING}),
    (:City => {name :: STRING NOT NULL, population :: INTEGER}),
    (:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City)
}

节点元素类型

节点元素类型由一个标识标签定义。节点元素类型确保所有具有标识标签的节点满足以下一个或多个条件:

  • 必须存在某些附加标签。这些附属标签被称为隐含标签

  • 必须存在某些属性。

  • 某些属性必须属于特定的属性类型。有关接受的属性类型列表,请参阅 值和类型 → 属性类型

图类型中的节点元素类型
(:Person => :Resident {name :: STRING NOT NULL}),  (1)
(:Pet => :Resident&Animal {healthCertificate :: STRING, name :: STRING}), (2)
(:City => {name :: STRING NOT NULL, population :: INTEGER}) (3)
1 节点元素类型确保带有 Person 标签的节点必须同时拥有 Resident 标签,且 Person 节点必须具有类型为 STRINGname 属性。Person 标签是此节点元素类型的标识标签,Resident 是隐含标签。
2 节点元素类型确保带有 Pet 标签的节点必须同时拥有 ResidentAnimal 标签。该节点元素类型还确保 Pet 节点上的任何 healthCertificatename 属性必须为 STRING 类型。Pet 标签是此节点元素类型的标识标签,而 ResidentAnimal 是隐含标签。
3 节点元素类型确保带有 City 标签的节点必须具有类型为 STRINGname 属性,且任何 population 属性必须为 INTEGER 类型。City 是此节点元素类型的标识标签,没有隐含标签。
NOT NULL 的等效速记语法是使用感叹号 !。例如,(:Person => :Resident {name :: STRING!}) 在语法上等同于 (:Person => :Resident {name :: STRING NOT NULL})
节点元素类型语法
(:IdentifyingLabel => [:ImpliedLabel1[&...]]  [“{“ {property1 :: <TYPE> [NOT NULL]}[, ...]”}”])

如果指定 ANY 作为 <TYPE>,节点元素类型将允许为给定属性分配所有有效的属性类型(仅当强制执行属性的存在性,即附加了 NOT NULL 时,才允许使用 ANY)。

关系元素类型

关系元素类型由一个标识类型定义。关系元素类型确保具有标识类型的关系满足以下一个或多个条件:

  • 源节点必须具有特定标签。

  • 目标节点必须具有特定标签。

  • 必须存在某些属性。

  • 某些属性必须属于特定的属性类型。有关接受的属性类型列表,请参阅 值和类型 → 属性类型

图类型中的关系元素类型
(:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City) (1)
1 关系元素类型确保所有标识类型为 LIVES_IN 的关系连接一个 Resident 节点和一个 City 节点,并具有类型为 DATEsince 属性。Resident 是源节点元素类型,City 是目标节点元素类型。
关系元素类型语法
([:SourceNodeLabel])-"[":IDENTIFYING_REL_TYPE => [ "{" {property1 :: <TYPE> [NOT NULL]}[, ...]"}" ] "]"->([:TargetNodeLabel])

关系元素类型不需要定义两个端节点。具体而言:

  • 如果关系元素类型定义了源节点或目标节点,则另一个不是必需的(例如,(:Resident)-[:LIVES_IN =>]->() 是可以接受的)。

  • 如果关系元素类型包含属性,则源节点和目标节点都是可选的(例如,()-[:LIVES_IN => {since :: DATE NOT NULL}]->() 是可以接受的)。

标识节点标签和关系类型

节点元素类型具有标识节点标签,关系元素类型具有标识关系类型。这些标识节点标签和关系类型用于在图类型中唯一标识节点或关系元素类型。例如,在 (:Person => :Resident {...}) 这样的节点元素类型定义中,Person 标签是标识标签,表示该节点元素类型代表具有 Person 标签的节点。

您不能拥有具有相同标识节点标签或关系类型的不同元素类型。

允许
(:Pet => :Resident&Animal {healthCertificate :: STRING, name :: STRING}),
(:Person)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
(:Person)-[:BORN_IN => {dob :: DATE NOT NULL})]->(:City)
不允许 —— 关系元素类型中的标识关系类型必须唯一
(:Person)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
(:Pet)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City)
不允许 —— 节点元素类型中的标识节点标签必须唯一
(:Person => :Resident {name :: STRING}),
(:Person => :Citizen {name :: STRING})

隐含节点标签及其在关系元素类型中的使用

节点元素类型还可以有一个或多个隐含标签(关系元素类型不能有隐含关系类型,因为 Neo4j 中的关系只能有一种类型)。这些标签进一步描述或细化了节点元素类型,添加了更多信息。例如,在 (:Person => :Resident {...}) 这样的节点元素类型定义中,Resident 是隐含标签,意味着该节点代表一个同时也是 ResidentPerson,但 Person 仍然是主要的标识符。

当多个元素节点类型共享隐含节点标签时,它们对于定义具有多个源或目标元素节点类型的关系元素类型非常有用。例如,如果 ResidentPersonPet 节点元素类型中的隐含标签,它也可以用作关系元素类型 LIVES_IN 的源节点。

允许
(:Person => :Resident {name :: STRING NOT NULL}),
(:Pet => :Resident&Animal {healthCertificate :: STRING, name :: STRING}),
(:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City)
不允许 —— 将节点标签既用作标识标签又用作隐含标签
(:Person => :Resident {name :: STRING NOT NULL}),
(:Resident => :Citizen {nationality :: STRING})
不允许 —— 关系元素类型中的标识关系类型必须唯一
(:Person => :Resident {name :: STRING NOT NULL}),
(:Pet => :Resident&Animal {healthCertificate :: STRING, name :: STRING}),
(:Person)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
(:Pet)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City)

标识节点标签和关系类型上的属性唯一性和键约束

到目前为止的示例中,节点和关系元素类型约束了以下内容:

  • 具有标识标签的节点和具有标识类型的关系上的特定属性类型。

  • 具有标识标签的节点和具有标识类型的关系上的特定属性的存在性。

  • 具有标识标签的节点上隐含标签的存在性。

  • 具有标识类型的关系的源节点和目标节点。

然而,节点和关系元素类型也可以定义为包含在其标识节点标签或关系类型上的属性唯一性约束。

设置一个包含标识节点标签键约束的图类型
ALTER CURRENT GRAPH TYPE SET {
    (p:Person => :Resident {name :: STRING, ssn :: INTEGER})
      REQUIRE (p.name, p.ssn) IS KEY, (1)
    (:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}), (2)
    (c:City => {name :: STRING NOT NULL, population :: INTEGER}),
    (:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(c)
}
1 节点元素类型确保带有 Person 标签的节点必须同时拥有 Resident 标签,且 Person 节点上的任何 namessn(社会安全号码)属性分别属于 STRINGINTEGER 类型。Person 节点元素类型定义了一个节点键约束,确保 Person 节点必须同时具有 namessn 属性,且它们的组合值必须唯一。
2 节点元素类型确保带有 Pet 标签的节点必须同时拥有 ResidentAnimal 标签。该节点元素类型定义了一个节点键约束,要求 Pet 节点具有唯一的 INTEGER 类型的 insuranceNumber 属性。该节点元素类型还确保 Pet 节点上的任何 healthCertificate 属性必须是唯一的且为 STRING 类型,并且任何 name 属性均为 STRING 类型。
上面的示例设置了一个新的图类型,从而替换了先前设置的图类型。它还使用变量来绑定节点元素类型。变量提供了一种引用图类型中指定的元素的简明方法,在使用 REQUIRE 关键字 时是必需的。

REQUIRE 关键字与复合属性唯一性和键约束

可以在节点或关系元素类型中定义单个属性唯一性和键约束,无论是否带有 REQUIRE 关键字。

使用和不使用 REQUIRE 关键字定义单个属性唯一性或键约束的语法
(n:Label => “{“property :: <TYPE> IS {UNIQUE | KEY} “}”),
(n:Label => “{“property :: <TYPE>”}”)
  REQUIRE n.property IS { UNIQUE | KEY }

()-”[“r:REL_TYPE => “{“property:: <TYPE> IS {UNIQUE | KEY} ”}”]->(),
()-”[“r:REL_TYPE => “{“property:: <TYPE>”}” “]”->()
  REQUIRE r.property IS { UNIQUE | KEY }

要在节点和关系元素类型中定义针对多个属性的复合唯一性和键约束,必须使用 REQUIRE 关键字,并且受约束的属性必须加括号。

定义复合属性唯一性或键约束的语法
(n:Label => “{“property1 :: <TYPE>, property2 :: <TYPE>[, ...]”}”)
  REQUIRE (n.property1, n.property2[, ...]) IS {UNIQUE | KEY}

()-”[“r:REL_TYPE => “{“property1:: <TYPE>, property2 :: <TYPE>[, ...] “}” “]”->()
  REQUIRE (r.property1, r.property2[, ...]) IS {UNIQUE | KEY}
REQUIRE 子句中指定的属性不需要存在于应用约束的节点或关系元素类型上。例如,以下是针对节点元素类型定义的有效元素类型键约束:(n:Label => {property1 :: STRING, property2 :: INTEGER}) REQUIRE (n.property3, n.property4) IS KEY

REQUIRE 关键字还可以作为一种替代语法,用于在同一个节点或关系元素类型中定义多个属性唯一性和键约束。

使用 REQUIRE 关键字定义多个属性唯一性或键约束的语法
(n:Label => “{“property1 :: <TYPE>, property2 :: <TYPE>”}”)
    REQUIRE n.property1 IS {UNIQUE | KEY}
    REQUIRE n.property2 IS {UNIQUE | KEY}

()-”[“r:REL_TYPE => “{“r.property1 :: <TYPE>, r.property2 :: <TYPE> “}” “]”->()
    REQUIRE r.property1 IS {UNIQUE | KEY}
    REQUIRE r.property2 IS {UNIQUE | KEY}

命名属性唯一性和键约束

属性唯一性和键约束也可以使用 CONSTRAINT … FOR … REQUIRE 语法创建。如果是这样,可以给它们指定一个名称,该名称在索引和约束中必须是唯一的(如果没有明确指定名称,将自动分配一个)。约束名称可以在 ALTER CURRENT GRAPH TYPE DROPDROP CONSTRAINT 命令中使用。有关详细信息,请参阅 删除标识和非标识节点标签及关系类型上的约束

以下两个示例定义了同一个标识节点标签上的键约束。然而,只有后者使用了 CONSTRAINT … FOR … REQUIRE 语法,并显式命名了它。

定义一个未显式命名的键约束
(p:Person => :Resident {name :: STRING, ssn :: INTEGER})
  REQUIRE (p.name, p.ssn) IS KEY
定义一个显式命名的键约束
(:Person => :Resident {name :: STRING, ssn :: INTEGER}),
CONSTRAINT name_ssn_constraint FOR (p:Person) REQUIRE (p.name, p.ssn) IS KEY
使用 CONSTRAINT … FOR … REQUIRE 语法定义单个属性唯一性或键约束
(:Label => “{“property :: <TYPE>”}”),
CONSTRAINT [name] FOR (n:Label) REQUIRE n.property IS {UNIQUE | KEY}

()-”[“:REL_TYPE => “{“property:: <TYPE>”}” “]”->(),
CONSTRAINT [name] FOR ()-”[“r:REL_TYPE”]”->() REQUIRE r.property IS {UNIQUE | KEY}
使用 CONSTRAINT … FOR … REQUIRE 语法定义复合属性唯一性或键约束
(:Label => “{“property1 :: <TYPE>, property2 :: <TYPE>”[, ...]}”),
CONSTRAINT [name] FOR (n:Label) REQUIRE (n.property1, n.property2[, ...]) IS {UNIQUE | KEY}

()-”[“:REL_TYPE => “{“property1 :: <TYPE>, property2 :: <TYPE>[, ...]”}” “]”->(),
CONSTRAINT [name] FOR ()-”[“r:REL_TYPE”]”->() REQUIRE (r.property1,r.property2[, ...]) IS {UNIQUE | KEY}

要在图类型中对不充当标识节点标签或关系类型的节点标签和关系类型定义约束,必须使用 CONSTRAINT … FOR … REQUIRE 语法。有关详细信息,请参阅下文的 非标识节点标签和关系类型上的约束

设置图类型后创建数据

图类型的目的是对其中包含的节点、关系和属性强加一种模式。在图中创建的数据必须相应地遵守图类型中定义的模式。

当前图类型
(p:Person => :Resident {name :: STRING, ssn :: INTEGER})
  REQUIRE (p.name, p.ssn) IS KEY,
(:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
(c:City => {name :: STRING NOT NULL, population :: INTEGER}),
(:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City)
创建符合图类型的数据
CREATE (alice:Person:Resident {name: 'Alice Carlyle', ssn: 987654321}),
       (ben:Person:Resident {name: 'Benjamin Davis', ssn: 456789123}),
       (ozzy:Pet:Resident:Animal {insuranceNumber: 876543210, healthCertificate: 'HC789123', name: 'Ozzy'}),
       (zoey:Pet:Resident:Animal {insuranceNumber: 564738291, name: 'Zoey'}),
       (nyc:City {name: 'New York City', population: 8097282}),
       (la:City {name: 'Los Angeles'}),
       (alice)-[:LIVES_IN {since: date('2018-06-15')}]->(nyc),
       (ozzy)-[:LIVES_IN {since: date('2022-08-09')}]->(nyc),
       (ben)-[:LIVES_IN {since: date('1999-10-17')}]->(la),
       (zoey)-[:LIVES_IN {since: date('2015-08-11')}]->(la)

请注意 'Zoey' Pet 节点上缺少 healthCertificate 属性,以及 'Los Angeles' City 节点上缺少 population 属性。图类型允许这些遗漏,因为这两种节点元素类型都不要求必须存在这些属性 —— 仅要求如果存在,它们必须符合指定的属性类型。

创建违反节点元素类型的数据
CREATE (:Person:Resident {name: 'Alice Carlyle', ssn: 987654321}) (1)
CREATE (:Person {name: 'Alice Carlyle', ssn: 123456789}) (2)
CREATE (:Person:Resident {name: 'Alice Carlyle'}) (3)
CREATE (:Person:Resident {name: 'Alice Carlyle', ssn: 'HNB48182'}) (4)
1 这将失败,因为它将创建一个属性与现有节点相同的节点,从而违反了 Person 节点元素类型中定义的键约束。
2 这将失败,因为 Person 节点元素类型要求带有 Person 标签的节点还必须具有 Resident 标签。
3 这将失败,因为 Person 节点元素类型中定义的图类型键约束(name, ssn)所包含的属性并未全部呈现。
4 这将失败,因为类型受约束的属性(ssn)的类型(STRING)与 Person 节点元素类型中为该属性定义的类型(INTEGER)不同。
创建违反关系元素类型的数据
CREATE (:Human {name: 'Carl Ericsson' ssn: 765498321})-[:LIVES_IN {since: date('1999-10-17')}]->(:City {name: 'Toronto'}) (1)
MATCH (alice:Person:Resident {name: 'Alice Carlyle'})
CREATE (alice)-[:LIVES_IN {since: date('1999-10-17')}]->(:Country {name: 'Canada'}) (2)
CREATE (alice)-[:LIVES_IN]->(:City {name: 'Toronto'}) (3)
CREATE (alice)-[:LIVES_IN {since: '1999-10-17'}]->(:City {name: 'Toronto'}) (4)
1 这将失败,因为 LIVES_IN 关系元素类型中定义的源节点必须具有 Resident 标签。
2 这将失败,因为 LIVES_IN 关系元素类型中定义的目标节点必须具有 City 标签。
3 这将失败,因为缺少 LIVES_IN 关系元素类型中定义的受存在性约束的属性(since)。
4 这将失败,因为类型受约束的属性(since)的类型(STRING)与 LIVES_IN 关系元素类型中为该属性定义的类型(DATE)不同。

开放图类型功能

使用开放图类型的最大好处是,它们允许您约束特定数据,同时在添加或修改未被图类型约束的数据时保持灵活性。

创建标签/类型在图类型中定义为标识性的节点和关系,但其属性未在各自的节点或关系元素类型中定义
CREATE (carl:Person:Resident {name: 'Carl Ericson', ssn: 162734679, born: date('1998-08-08')}), (1)
       (molly:Pet:Resident:Animal {name: 'Molly', insuranceNumber: 672829172, healthCertificate: 'HT654987', breed: 'Alsatian'}), (2)
       (atlanta:City {name: 'Atlanta', population: 2794356, country: 'USA'}), (3)
       (carl)-[:LIVES_IN {since: date('2020-09-15'), address: '101, Jasper Avenue'}]->(atlanta)<-[:LIVES_IN {since: date('2022-10-22')}]-(molly) (4)
1 Person 节点元素类型中没有定义 born 属性。
2 Pet 节点元素类型中没有定义 breed 属性。
3 City 节点元素类型中没有定义 country 属性。
4 LIVES_IN 关系元素类型中没有定义 address 属性。
创建带有隐含标签但没有标识标签的节点
CREATE (:StrayAnimal:Animal:Resident {id: '24.09-172898'}),
       (:Robot:Resident {name: 'Gary', application: 'Veterinary medicine'})
创建带有图类型中未包含的节点标签和关系类型的节点
MATCH (ben:Person {name: 'Benjamin Davis'}), (zoey:Pet {name: 'Zoey'}), (gary:Robot {name: 'Gary'})
CREATE (ben)-[:OWNER_OF {ownershipId: 'GTHD-985'}]->(zoey),
       (ben)-[:WORKS_FOR {role: 'Product Manager'}]->(healthyPets:Company {name: 'Healthy Pets Inc.', address: '4567 Wellness Drive, Los Angeles, CA 90001'}),
       (gary)-[:INSTALLED_AT]->(healthyPets)

在已填充数据的数据库上设置图类型

如果数据库包含与图类型要求相冲突的数据,则只有在修改任何冲突数据以符合其模式后,才有可能设置所需的图类型。因此,在已填充数据的数据库上设置图类型将涉及对现有数据的检查。请注意,当设置图类型时,任何先前定义的图类型都将被覆盖并替换。

在包含上一节中所创建数据的数据库中,无法设置以下图类型

不允许 —— 设置与现有数据冲突的图类型
ALTER CURRENT GRAPH TYPE SET {
  (p:Person => :Resident {name :: STRING, ssn :: INTEGER})
    REQUIRE (p.name, p.ssn) IS KEY,
  (:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
  (:City => {name :: STRING NOT NULL, population :: INTEGER}),
  (:Robot => :Resident {name :: STRING, id :: INTEGER IS KEY}), (1)
  (:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
  (:Person)-[r:OWNER_OF => {ownershipId :: INTEGER IS UNIQUE})->(:Pet) (2)
}
1 此节点元素类型无法验证,因为它要求每个 Robot 节点必须具有一个唯一的 INTEGER 类型的 id 属性(先前创建的 Robot 节点没有 id 属性)。
2 此关系元素类型无效,因为它要求 OWNER_OF 关系上的任何 ownershipId 属性必须为 INTEGER 类型(先前创建的 OWNER_OF 关系具有 STRING 类型的 ownershipId 属性)。

当出现上述情况时,用户应将现有数据迁移到新的所需模型,然后应用新的图类型,这将确保此后的数据保持一致。

非标识节点标签和关系类型上的约束

到目前为止的示例中,包括了节点和关系元素类型,以及定义在标识节点标签和关系类型上的属性唯一性和键约束。

也可以使用上述 CONSTRAINT … FOR … REQUIRE 语法,在图类型中包含隐含节点标签上的约束,或包含独立于节点或关系元素类型的节点标签和关系类型上的约束。如果数据模型要求非标识标签或类型的节点或关系具有某些属性,这可能是一个有用的工具。

非标识节点标签和关系类型上的约束可以在定义时显式命名。这在 删除标识和非标识节点标签及关系类型上的约束 时会很有用(如果未显式给出名称,将自动分配一个名称)。给定的名称在索引和约束中必须唯一。

属性唯一性和键约束可以针对图中的任何节点标签或关系类型定义,无论它们是否充当标识节点标签或关系类型(定义在节点元素类型的标识节点标签上的键约束示例可在 上文 中找到)。

设置一个对非标识节点标签具有键约束和属性唯一性约束的图类型
ALTER CURRENT GRAPH TYPE SET {
  (p:Person => :Resident {name :: STRING, ssn :: INTEGER})
    REQUIRE (p.name, p.ssn) IS KEY,
  (:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
  (:City => {name :: STRING NOT NULL, population :: INTEGER}),
  (:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
  CONSTRAINT company_name FOR (c:Company) REQUIRE c.name IS KEY, (1)
  CONSTRAINT animal_id FOR (a:Animal) REQUIRE a.id IS UNIQUE (2)
}
1 针对不属于图类型中任何元素类型(作为标识或隐含)的节点标签(:Company)定义的节点键约束。
2 针对在 Pet 节点元素类型中充当隐含标签的节点标签(:Animal)定义的属性唯一性约束。
上面的示例设置了一个新的图类型,从而替换了先前设置的图类型

属性存在性属性类型约束也可以定义在非标识标签和关系类型上。但是,与属性唯一性和键约束不同,如果它们定义在节点或关系元素类型之外,则不能约束标识节点标签或关系类型。这是因为节点和关系元素类型可以直接表达属性存在性和属性类型约束对标识节点标签或关系类型的影响。

允许 —— 在节点元素类型中定义属性存在性约束
(:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING, address :: ANY NOT NULL})
不允许 —— 在节点元素类型之外的标识节点标签上添加属性存在性约束
(:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
CONSTRAINT pet_address FOR (pet:Pet) REQUIRE pet.address IS NOT NULL
如果属性存在性和类型约束在节点或关系元素类型中表达,则不能命名(它们总是会被分配一个生成的名称)。有关详细信息,请参阅 显示图类型 → SHOW CONSTRAINTS 中的图类型元素

因此,大多数用例都可以由图类型中的节点和关系元素类型来满足。然而,在非标识节点标签或关系类型上添加属性存在性和类型约束,对于定义更专门的约束可能很有用,尤其是在已经填充数据的数据库中。

设置一个包含非标识节点标签属性类型约束的图类型
ALTER CURRENT GRAPH TYPE SET {
  (p:Person => :Resident {name :: STRING, ssn :: INTEGER})
    REQUIRE (p.name, p.ssn) IS KEY,
  (:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
  (:Robot => :Resident {application :: STRING NOT NULL}),
  (:City => {name :: STRING NOT NULL, population :: INTEGER}),
  (:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
  CONSTRAINT company_name FOR (c:Company) REQUIRE c.name IS KEY,
  CONSTRAINT animal_id FOR (a:Animal) REQUIRE a.id IS UNIQUE,
  CONSTRAINT resident_address FOR (resident:Resident) REQUIRE resident.address IS :: STRING (1)
}
1 属性类型约束,确保 RESIDENT 节点上的任何地址属性均为 STRING 类型。此约束是有效的,因为 Resident 在上述任何节点元素类型中都不是标识标签。
上面的示例设置了一个新的图类型,从而替换了先前设置的图类型

图类型实现:转换为约束

一旦定义了图类型,它就会被转换为一组约束。这些约束确保图的创建和发展符合图类型指定的开放模式。

强制执行图类型的约束由 SHOW CONSTRAINTS 命令返回。有关详细信息,请参阅 显示图类型 → SHOW CONSTRAINTS 中的图类型元素

当前图类型
(p:Person => :Resident {name :: STRING, ssn :: INTEGER})
   REQUIRE (p.name, p.ssn) IS KEY,
(:Pet => :Resident&Animal {insuranceNumber :: INTEGER IS KEY, healthCertificate :: STRING IS UNIQUE, name :: STRING}),
(:Robot => :Resident {application :: STRING NOT NULL}),
(:City => {name :: STRING NOT NULL, population :: INTEGER}),
(:Resident)-[:LIVES_IN => {since :: DATE NOT NULL}]->(:City),
CONSTRAINT company_name FOR (c:Company) REQUIRE c.name IS KEY,
CONSTRAINT animal_id FOR (a:Animal) REQUIRE a.id IS UNIQUE,
CONSTRAINT resident_address FOR (resident:Resident) REQUIRE resident.address :: STRING
节点和关系元素类型
标识节点标签/关系类型 约束类型 详细信息

(:Person)

节点属性类型

name :: STRING

(:Person)

节点属性类型

ssn :: INTEGER

(:Person)

节点标签存在性

带有 Person 标签的节点必须还拥有 Resident 标签。

(:Pet)

节点属性类型

insuranceNumber :: INTEGER

(:Pet)

节点属性类型

healthCertificate :: STRING

(:Pet)

节点属性类型

name :: STRING

(:Pet)

节点标签存在性

带有 Pet 标签的节点必须还拥有 Resident 标签。

(:Pet)

节点标签存在性

带有 Pet 标签的节点必须还拥有 Animal 标签。

(:Robot)

节点属性类型

application :: STRING

(:Robot)

节点属性存在性

application IS NOT NULL

(:Robot)

节点标签存在性

带有 Robot 标签的节点必须还拥有 Resident 标签。

(:City)

节点属性类型

name :: STRING

(:City)

节点属性存在性

name IS NOT NULL

(:City)

节点属性类型

population :: INTEGER

()-[:LIVES_IN]->()

关系属性类型

since :: DATE

()-[:LIVES_IN]->()

关系属性存在性

since IS NOT NULL

()-[:LIVES_IN]->()

关系源标签

源节点必须具有标签 Resident

()-[:LIVES_IN]->()

关系目标标签

目标节点必须具有标签 City

标识节点标签和关系类型的键和属性唯一性约束
标识节点标签/关系类型 约束类型 详细信息

(:Person)

节点键

(name, ssn) IS KEY

(:Pet)

节点键

insuranceNumber IS KEY

(:Pet)

节点属性唯一性

healthCertificate IS UNIQUE

非标识节点标签上的约束
名称 节点标签/关系类型 约束类型 详细信息

company_name

(:Company)

节点键

name IS KEY

animal_id

(:Animal)

节点属性唯一性

id IS UNIQUE

resident_address

(:Resident)

节点属性类型

name :: STRING

约束类型说明

节点标签存在性约束确保节点上存在特定的标签。此约束仅在节点元素类型指定隐含标签时才会创建,且不能使用 CREATE CONSTRAINT 命令创建。

关系源和目标标签约束确保特定的关系类型具有带有特定标签的目标节点和源节点。关系源标签约束仅在关系元素类型指定源节点时创建。关系目标标签约束仅在关系类型指定目标节点时创建。这些约束都不能使用 CREATE CONSTRAINT 命令创建。

属性类型约束确保属性对于所有具有特定标签的节点或所有具有特定类型的关系具有所需的属性类型。要了解有关属性类型约束以及如何使用 CREATE CONSTRAINT 语法创建它们的更多信息,请参阅 约束 → 创建属性类型约束

属性存在性约束确保属性存在于所有具有特定标签的节点或所有具有特定类型的关系上。要了解有关属性存在性约束以及如何使用 CREATE CONSTRAINT 命令创建它们的更多信息,请参阅 约束 → 创建属性存在性约束

属性唯一性约束确保组合属性值对于所有具有特定标签的节点或所有具有特定类型的关系是唯一的。要了解有关属性唯一性约束以及如何使用 CREATE CONSTRAINT 命令创建它们的更多信息,请参阅 约束 → 创建属性唯一性约束

键约束确保所有属性都存在,且对于所有具有特定标签的节点或所有具有特定类型的关系,组合属性值是唯一的。要了解有关键约束以及如何使用 CREATE CONSTRAINT 命令创建它们的更多信息,请参阅 约束 → 创建键约束