CREATE
节点语法
CREATE
子句允许您创建一个或多个节点。每个节点都可以被赋予标签和属性。您可以将每个节点绑定到一个变量,以便在后续查询中引用。多个标签用冒号分隔。
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'}), (oliver:Person:Director {name: 'Oliver Stone'})
从 Neo4j 5.18 开始,多个标签也可以用连接符 &
分隔,其方式与在标签表达式中使用的方式相同。冒号 :
和连接符 &
不能在同一个子句中混用。
CREATE (charlie:Person&Actor {name: 'Charlie Sheen'}), (oliver:Person&Director {name: 'Oliver Stone'})
上述两个查询都创建了两个节点,分别绑定到变量 charlie
和 oliver
,每个节点都带有 Person
标签和 name
属性。代表查理·辛的节点还带有 Actor
标签,而代表奥利弗·斯通的节点则被赋予 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'})
此查询创建了查理·辛和奥利弗·斯通的 Person
节点,以及《华尔街》的 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
和 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)
创建了查理·辛、奥利弗·斯通和迈克尔·道格拉斯的所有三个节点,并将它们全部连接到代表《华尔街》电影的节点。然后返回从查理·辛到奥利弗·斯通的路径长度。
请注意,当重复节点的变量时,您不能向重复的变量添加标签或属性。
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})
此查询试图创建节点,使查理的得分高于奥利弗的得分,反之亦然,这自相矛盾。因此查询失败。
在 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 | labels | relType | movies |
---|---|---|---|
|
|
|
|
行数: 1 |
INSERT
作为 CREATE
的同义词
INSERT
可用作 CREATE
的同义词,用于创建节点和关系,并作为 Cypher GQL 一致性的一部分引入。但是,INSERT
要求多个标签通过连接符 &
分隔,而不是冒号 :
。此外,INSERT
不支持使用动态节点标签和关系类型。
INSERT (tom:Person&Actor&Director {name: 'Tom Hanks'})
创建了一个节点,绑定到变量 tom
,带有 Person
、Actor
和 Director
标签以及一个 name
属性。