我可以在Neo4j Cypher中设置地图而不覆盖现有属性

时间:2018-11-20 16:27:06

标签: neo4j cypher

我有地图说

car: {make: toyota, color: blue, model: camry} 

我有一个节点Car,其属性为

make: toyota

现在,我想将地图汽车中的属性添加到我的节点Car

但是

MATCH (n:Car {make:'toyota'}) 
SET n +=car 
RETURN n;

将覆盖我节点上的make属性。

有办法避免这种情况吗?

用例是当make是节点的关键属性时,我不想意外更改它,当然我也不想抛出错误。

2 个答案:

答案 0 :(得分:0)

如果尝试在一个查询中执行此操作,则必须制作一个WHERE子句以捕获所有NULL的属性。因此,您将需要使用WITH子句来传递这些记录,并使用另一个WHERE子句来选择仅缺少一个属性的记录。问题是从第一个WHERE子句回到记录。这可能是可行的,但是如果是这样,我不知道该如何使用Cypher。

对每个属性使用多个查询,只需在IS NULL子句中添加WHERE即可轻松实现。

为了说明这一点,创建了一组具有不同属性组合和缺失属性的记录。

CREATE (:Car {make: "toyota", color: "red", model: "prius", car_id: 01} )
CREATE (:Car {make: "toyota", color: "red", car_id: 02} )
CREATE (:Car {make: "toyota", model: "prius", car_id: 03} )
CREATE (:Car {make: "toyota", car_id: 04} );

查看创建的内容

MATCH (n) RETURN n.make,n.model,n.color,n.car_id,LABELS(n);

╒════════╤═════════╤═════════╤══════════╤═══════════╕
│"n.make"│"n.model"│"n.color"│"n.car_id"│"LABELS(n)"│
╞════════╪═════════╪═════════╪══════════╪═══════════╡
│"toyota"│"prius"  │"red"    │1         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│null     │"red"    │2         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│"prius"  │null     │3         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│null     │null     │4         │["Car"]    │
└────────┴─────────┴─────────┴──────────┴───────────┘

仅更新颜色属性

MATCH (c:Car {make:"toyota"}) 
WHERE c.color IS NULL 
SET c += {color: "blue"}
RETURN c;

看看有什么变化

MATCH (n) RETURN n.make,n.model,n.color,n.car_id,LABELS(n);

╒════════╤═════════╤═════════╤══════════╤═══════════╕
│"n.make"│"n.model"│"n.color"│"n.car_id"│"LABELS(n)"│
╞════════╪═════════╪═════════╪══════════╪═══════════╡
│"toyota"│"prius"  │"red"    │1         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│null     │"red"    │2         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│"prius"  │"blue"   │3         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│null     │"blue"   │4         │["Car"]    │
└────────┴─────────┴─────────┴──────────┴───────────┘

请注意,只有没有颜色属性的汽车才会更新。

model

做同样的事情
MATCH (m:Car {make:"toyota"}) 
WHERE m.model IS NULL
SET m += {model: "camry"} 
RETURN m;

MATCH (n) RETURN n.make,n.model,n.color,n.car_id,LABELS(n);

╒════════╤═════════╤═════════╤══════════╤═══════════╕
│"n.make"│"n.model"│"n.color"│"n.car_id"│"LABELS(n)"│
╞════════╪═════════╪═════════╪══════════╪═══════════╡
│"toyota"│"prius"  │"red"    │1         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│"camry"  │"red"    │2         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│"prius"  │"blue"   │3         │["Car"]    │
├────────┼─────────┼─────────┼──────────┼───────────┤
│"toyota"│"camry"  │"blue"   │4         │["Car"]    │
└────────┴─────────┴─────────┴──────────┴───────────┘

答案 1 :(得分:0)

您可以使用apoc.map.clean从地图中删除某些键和值:

SET c += apoc.map.clean(car, ['make'],[])