SET
SET 子句用于更新节点上的标签,以及节点和关系上的属性。
SET 子句可以与映射(以字面量或参数形式提供)配合使用来设置属性。
|
在节点上设置标签是一个幂等操作——如果尝试为一个已经拥有该标签的节点设置相同的标签,则不会发生任何变化。查询统计信息将说明是否确实进行了任何更新。 |
示例图
以下图表用于下方的示例
要重新创建它,请在空的 Neo4j 数据库中运行以下查询
CREATE
(a:Swedish {name: 'Andy', age: 36, hungry: true}),
(b {name: 'Stefan'}),
(c {name: 'Peter', age: 34}),
(d {name: 'George'}),
(a)-[:KNOWS]->(c),
(b)-[:KNOWS]->(a),
(d)-[:KNOWS]->(c)
设置属性
更新节点属性
MATCH (n {name: 'Andy'})
SET n.surname = 'Taylor'
RETURN n.name, n.surname
查询将返回更新后的节点。
| n.name | n.surname |
|---|---|
|
|
行:1 |
|
更新关系属性
MATCH (n:Swedish {name: 'Andy'})-[r:KNOWS]->(m)
SET r.since = 1999
RETURN r, m.name AS friend
| r | friend |
|---|---|
|
|
行:1 |
|
可以使用更复杂的表达式在节点或关系上设置属性。例如,与直接指定节点不同,以下查询展示了如何为通过表达式选择的节点设置属性
MATCH (n {name: 'Andy'})
SET (CASE WHEN n.age = 36 THEN n END).worksIn = 'Malmo'
RETURN n.name, n.worksIn
| n.name | n.worksIn |
|---|---|
|
|
行:1 |
|
如果节点表达式的计算结果为 null,则不会采取任何操作,如下例所示
MATCH (n {name: 'Andy'})
SET (CASE WHEN n.age = 55 THEN n END).worksIn = 'Malmo'
RETURN n.name, n.worksIn
由于没有节点匹配 CASE 表达式,该表达式返回 null。因此,不会发生任何更新,也就不会设置 worksIn 属性。
| n.name | n.worksIn |
|---|---|
|
|
行:1 |
|
更新属性
SET 可用于更新节点或关系上的属性。此查询强制更改 age 属性的类型
MATCH (n {name: 'Andy'})
SET n.age = toString(n.age)
RETURN n.name, n.age
age 属性已被转换为 STRING 类型的 '36'。
| n.name | n.age |
|---|---|
|
|
行:1 |
|
动态设置或更新属性
即使属性键名不是静态已知的,SET 也可以用来设置或更新节点或关系上的属性。这使得查询更加灵活,并降低了 Cypher® 注入的风险。(有关 Cypher 注入的更多信息,请参阅 Neo4j 知识库 → 防止 Cypher 注入)。
SET n[key] = expression
动态计算出的键必须计算为 STRING 值。此查询会创建节点上每个属性的副本
MATCH (n)
FOREACH (k IN keys(n) | SET n[k + "Copy"] = n[k]) (1)
RETURN n.name, keys(n);
现在节点拥有了它们所有属性的副本。
| n.name | keys(n) |
|---|---|
|
|
|
|
|
|
|
|
行:4 |
|
删除属性
尽管 REMOVE 通常用于删除属性,但有时使用 SET 命令来完成会更方便。例如,如果属性是由参数提供的。
MATCH (n {name: 'Andy'})
SET n.name = null
RETURN n.name, n.age
name 属性现在缺失。
| n.name | n.age |
|---|---|
|
|
行:1 |
|
在节点和关系之间复制属性
SET 可以与 properties() 函数一起使用,将一个节点或关系的所有属性复制到另一个。这将删除被复制目标节点或关系上的所有其他属性。
MATCH
(at {name: 'Andy'}),
(pn {name: 'Peter'})
SET at = properties(pn)
RETURN at.name, at.age, at.hungry, pn.name, pn.age
'Andy' 节点的所有属性已被 'Peter' 节点的属性所替换。
| at.name | at.age | at.hungry | pn.name | pn.age |
|---|---|---|---|---|
|
|
|
|
|
行:1 |
||||
使用映射和 = 替换所有属性
属性替换运算符 = 可以与 SET 一起使用,将节点或关系上的所有现有属性替换为映射中提供的属性
MATCH (p {name: 'Peter'})
SET p = {name: 'Peter Smith', position: 'Entrepreneur'}
RETURN p.name, p.age, p.position
此查询将 'Peter' 节点的 name 属性从 Peter 更新为 Peter Smith,删除了 age 属性,并添加了 position 属性。
| p.name | p.age | p.position |
|---|---|---|
|
|
|
行:1 |
||
使用空映射和 = 删除所有属性
通过将 SET 与 = 和右操作数为空映射配合使用,可以从节点或关系中删除所有现有属性
MATCH (p {name: 'Peter'})
SET p = {}
RETURN p.name, p.age
此查询从 'Peter' 节点中删除了所有现有属性,即 name 和 age。
| p.name | p.age |
|---|---|
|
|
行:1 |
|
使用映射和 += 修改特定属性
属性修改运算符 += 可与 SET 一起使用,以细粒度的方式从映射中修改属性
-
映射中存在而节点或关系上不存在的任何属性都将被添加。
-
节点或关系上存在但映射中不存在的任何属性将保持原样。
-
在映射和节点或关系中同时存在的任何属性都将在节点或关系中被替换。但是,如果映射中的任何属性值为
null,它将从节点或关系中被删除。
MATCH (p {name: 'Peter'})
SET p += {age: 38, hungry: true, position: 'Entrepreneur'}
RETURN p.name, p.age, p.hungry, p.position
此查询使 name 属性保持不变,将 age 属性从 34 更新为 38,并将 hungry 和 position 属性添加到 'Peter' 节点。
| p.name | p.age | p.hungry | p.position |
|---|---|---|---|
|
|
|
|
行:1 |
|||
与属性替换运算符 = 不同,将空映射作为右操作数传递给 += 不会从节点或关系中删除任何现有属性。根据上述语义,传入带有 += 的空映射将不会产生任何影响
MATCH (p {name: 'Peter'})
SET p += {}
RETURN p.name, p.age
| p.name | p.age |
|---|---|
|
|
行:1 |
|
使用一个 SET 子句设置多个属性
通过用逗号分隔,一次设置多个属性
MATCH (n {name: 'Andy'})
SET n.position = 'Developer', n.surname = 'Taylor'
|
行数:0 |
使用参数设置属性
使用参数设置属性的值
{
"surname": "Taylor"
}
MATCH (n {name: 'Andy'})
SET n.surname = $surname
RETURN n.name, n.surname
surname 属性已被添加到 'Andy' 节点。
| n.name | n.surname |
|---|---|
|
|
行:1 |
|
使用参数设置所有属性
这将用参数提供的新属性集替换节点上的所有现有属性。
{
"props" : {
"name": "Andy",
"position": "Developer"
}
}
MATCH (n {name: 'Andy'})
SET n = $props
RETURN n.name, n.position, n.age, n.hungry
'Andy' 节点的所有属性已被 props 参数中的属性所替换。
| n.name | n.position | n.age | n.hungry |
|---|---|---|---|
|
|
|
|
行:1 |
|||
在节点上设置标签
使用 SET 在节点上设置标签
MATCH (n {name: 'Stefan'})
SET n:German
RETURN n.name, labels(n) AS labels
查询将返回新标记的节点。
| n.name | 标签 |
|---|---|
|
|
行:1 |
|
动态设置节点标签
即使标签不是静态已知的,SET 也可以用来在节点上设置标签。
MATCH (n)
SET n:$(<expr>)
MATCH (n:Swedish)
SET n:$(n.name)
RETURN n.name, labels(n) AS labels
查询将返回新标记的节点。
| n.name | 标签 |
|---|---|
|
|
行:1 |
|
使用参数设置标签
使用参数设置标签的值
{
"label": "Danish"
}
MATCH (n {name: 'Stefan'})
SET n:$($label)
RETURN labels(n) AS labels
Danish 标签已被添加到 'Stefan' 节点。
| 标签 |
|---|
|
行:1 |
在节点上设置多个标签
使用 SET 在节点上设置多个标签,并使用 : 分隔不同的标签
MATCH (n {name: 'George'})
SET n:Swedish:Bossman
RETURN n.name, labels(n) AS labels
查询将返回新标记的节点。
| n.name | 标签 |
|---|---|
|
|
行:1 |
|
动态设置节点上的多个标签
可以使用 LIST<STRING> 和/或通过使用 : 分别进行链式调用来动态设置多个标签
WITH COLLECT { UNWIND range(0,3) AS id RETURN "Label" + id } as labels (1)
MATCH (n {name: 'George'})
SET n:$(labels)
RETURN n.name, labels(n) AS labels
| 1 | COLLECT 子查询聚合了 UNWIND range(0,3) AS id RETURN "Label" + id 的结果,该结果生成一个 LIST<STRING> 字符串列表("Label0", "Label1", "Label2", "Label3"),并将其分配给变量 labels。 |
查询将返回新标记的节点。
| n.name | 标签 |
|---|---|
|
|
行:1 |
|