CREATE
简介
CREATE 子句允许您创建节点和关系。为了定义这些实体,CREATE 使用了与 MATCH 类似的语法。然而,尽管 模式 (patterns) 只需计算为真或假,但 CREATE 的语法需要精确指定要创建的节点和关系。
节点语法
CREATE 子句允许您创建一个或多个节点。每个节点都可以被分配标签和属性。您可以将每个节点绑定到一个变量,以便在查询的后续部分引用它。多个标签之间用冒号分隔。
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'}), (oliver:Person:Director {name: 'Oliver Stone'})
多个标签也可以像 标签表达式 中那样,使用“与”符号 & 分隔。在同一个子句中不能混合使用冒号 : 和“与”符号 & 进行分隔。
CREATE (charlie:Person&Actor {name: 'Charlie Sheen'}), (oliver:Person&Director {name: 'Oliver Stone'})
上述两个查询都创建了两个节点,分别绑定到变量 charlie 和 oliver,每个节点都有一个 Person 标签和一个 name 属性。代表 Charlie Sheen 的节点还带有 Actor 标签,而代表 Oliver Stone 的节点则被分配了 Director 标签。
关系语法
也可以使用 CREATE 子句创建关系。与节点不同,关系总是需要确切的一个关系类型和方向。与节点类似,关系可以被分配属性和关系类型,并绑定到变量。
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'})-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver:Person:Director {name: 'Oliver Stone'})
此查询为 Charlie Sheen 和 Oliver Stone 创建了 Person 节点,并为《华尔街》(Wall Street) 创建了 Movie 节点。它还在它们之间创建了类型为 ACTED_IN 和 DIRECTED 的关系。
重用变量
前面的示例在指定的节点之间创建了一条路径。请注意,这些新创建的节点和关系与图中已存在的内容并不相连。要将它们与已存在的数据连接起来,请将所需的节点和关系绑定到变量。然后,这些变量可以传递给查询中针对图中现有元素的后续子句。
MATCH (charlie:Person {name: 'Charlie Sheen'}), (oliver:Person {name: 'Oliver Stone'})
CREATE (charlie)-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver)
在此示例中,MATCH 子句查找 Charlie Sheen 和 Oliver Stone 的节点,并分别将它们绑定到 charlie 和 oliver 变量。这些变量随后传递给后续的 CREATE 子句,该子句从已绑定的节点创建新的关系。
您还可以在同一个或后续子句中重用来自同一个 CREATE 的变量。通过这种方式,例如,您可以定义比简单的线性路径更复杂的结构。
CREATE p = (charlie:Person:Actor {name: 'Charlie Sheen'})-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver:Person:Director {name: 'Oliver Stone'}), (wallStreet)<-[:ACTED_IN {role: 'Gordon Gekko'}]-(michael:Person:Actor {name: 'Michael Douglas'})
RETURN length(p)
为 Charlie Sheen、Oliver Stone 和 Michael Douglas 创建了所有三个节点,并将它们全都连接到代表《华尔街》电影的节点。然后,它返回从 Charlie Sheen 到 Oliver Stone 的路径长度。
请注意,当重复使用某个节点的变量时,不得在该重复引用中添加标签或属性。
MATCH (charlie:Person {name: 'Charlie Sheen'})
CREATE (charlie:Actor)
此查询将会失败,因为变量 charlie 已经绑定到一个预先存在的节点,因此它不能被重用来创建一个新节点。如果您打算添加标签,请改用 SET 子句。
在属性中重用变量
可以分配给节点或关系属性的值,可以通过 表达式 来定义。
MATCH (person:Person)
WHERE person.name IS NOT NULL
CREATE (anotherPerson:Person {name: person.name, age: $age})
此示例创建了一个 Person 节点,其姓名与另一个人相同,年龄来自名为 age 的 参数。
此类表达式不得包含对同一 CREATE 语句中定义的变量的引用。这是为了确保属性的值始终明确。
CREATE (charlie {score: oliver.score + 1}), (oliver {score: charlie.score + 1})
此查询试图创建这样的节点:Charlie 的分数高于 Oliver 的分数,反之亦然,这是一个矛盾。因此,该查询失败。
将参数与 CREATE 一起使用
使用动态节点标签和关系类型的 CREATE
在创建节点和关系时,可以在表达式、参数和变量中动态引用节点标签和关系类型。这允许更灵活的查询,并降低了 Cypher 注入的风险。(有关 Cypher 注入的更多信息,请参阅 Neo4j 知识库 → 防御 Cypher 注入)。
CREATE (n:$(<expr>))
CREATE ()-[r:$(<expr>)]->()
表达式必须计算为 STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL 值。在使用动态关系类型创建关系时,使用包含多于一项的 LIST<STRING> 将会失败。这是因为一个关系只能拥有且仅拥有一个类型。
{
"nodeLabels": ["Person", "Director"],
"relType": "DIRECTED",
"movies": ["Ladybird", "Little Women", "Barbie"]
}
CREATE (greta:$($nodeLabels) {name: 'Greta Gerwig'})
WITH greta
UNWIND $movies AS movieTitle
CREATE (greta)-[rel:$($relType)]->(m:Movie {title: movieTitle})
RETURN greta.name AS name, labels(greta) AS labels, type(rel) AS relType, collect(m.title) AS movies
| 名称 (name) | 标签 | relType | movies |
|---|---|---|---|
|
|
|
|
行:1 |
|||
INSERT 作为 CREATE 的同义词
INSERT 可用作 CREATE 的同义词来创建节点和关系,它是作为 Cypher GQL 一致性 的一部分引入的。但是,INSERT 要求多个标签使用“与”符号 & 分隔,而不是使用冒号 :。此外,INSERT 不支持使用动态节点标签和关系类型。
INSERT (tom:Person&Actor&Director {name: 'Tom Hanks'})
创建一个节点,绑定到变量 tom,带有 Person、Actor 和 Director 标签以及一个 name 属性。