我想替换' Amount'的价值。键入地图(字面值),其中包含现有'金额'价值加上新的金额'这样的价值,如果'类型'和' Price'比赛。我到目前为止的结构是:
WITH [{type:1, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]},
{type:2, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]},
{type:3, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]}] as ExistingOrders,
{type:2, Order:{Price:11,Amount:50}} as NewOrder
(我试图让它:)
RETURN [{type:1,Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]}, {type:2,Orders:[{Price:10,Amount:100},{Price:11,Amount: 250 },{Price:12,Amount:300}]}, {type:3,Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]}] as CombinedOrders < / p>
如果没有现有的NewOrder.type和NewOrder.Price,那么显然应该插入新记录而不是将它们加在一起。
对不起,这可能非常简单,但我还不是很擅长。
感谢
修改
我应该补充一点,我已经能够使这个更简单的地图结构:
WITH [{type:1, Amount:100},{type:2, Amount:200},{type:3, Amount:300}] as ExistingOrders,
{type:2, Amount:50} as NewValue
RETURN reduce(map=filter(p in ExistingOrders where not p.type=NewValue.type),x in [(filter(p2 in ExistingOrders where p2.type=NewValue.type)[0])]|CASE x WHEN null THEN NewValue ELSE {type:x.type,Amount:x.Amount+NewValue.Amount} END+map) as CombinedOrders
但是我觉得因为我的第一个例子中的Orders [数组]而苦苦挣扎。
答案 0 :(得分:2)
我认为您只是想更新Amount
中相应ExistingOrders
的值。
以下查询是合法的Cypher,应该正常工作:
WITH ExistingOrders, NewOrder, [x IN ExistingOrders WHERE x.type = NewOrder.type | x.Orders] AS eo
FOREACH (y IN eo |
SET y.Amount = y.Amount + CASE WHEN y.Price = NewOrder.Order.Price THEN NewOrder.Order.Amount ELSE 0 END
)
但是,上述查询会在消息中产生(有些)有趣的ThisShouldNotHappenError
错误:
开发人员:Stefan声称:这应该是节点或关系
消息试图说的是(以钝的方式)是你没有以正确的方式使用neo4j DB。您的属性太复杂了,应该分成节点和关系。
所以,我将提出一个能够做到这一点的数据模型。以下是如何创建表示与ExistingOrders相同的数据的节点和关系:
CREATE (t1:Type {id:1}), (t2:Type {id:2}), (t3:Type {id:3}),
(t1)-[:HAS_ORDER]->(:Order {Price:10,Amount:100}),
(t1)-[:HAS_ORDER]->(:Order {Price:11,Amount:200}),
(t1)-[:HAS_ORDER]->(:Order {Price:12,Amount:300}),
(t2)-[:HAS_ORDER]->(:Order {Price:10,Amount:100}),
(t2)-[:HAS_ORDER]->(:Order {Price:11,Amount:200}),
(t2)-[:HAS_ORDER]->(:Order {Price:12,Amount:300}),
(t3)-[:HAS_ORDER]->(:Order {Price:10,Amount:100}),
(t3)-[:HAS_ORDER]->(:Order {Price:11,Amount:200}),
(t3)-[:HAS_ORDER]->(:Order {Price:12,Amount:300});
这是一个更新正确的Amount
:
WITH {type:2, Order:{Price:11,Amount:50}} as NewOrder
MATCH (t:Type)-[:HAS_ORDER]->(o:Order)
WHERE t.id = NewOrder.type AND o.Price = NewOrder.Order.Price
SET o.Amount = o.Amount + NewOrder.Order.Amount
RETURN t.id, o.Price, o.Amount;
答案 1 :(得分:1)
你的问题分为两部分 - 一部分是简单的答案,第二部分是没有意义的。让我先拿一个简单的!
据我所知,您似乎在询问如何将新地图连接到地图集合。那么,如何在数组中添加新项。只需使用+
就像这个简单的例子:
return [{item:1}, {item:2}] + [{item:3}];
请注意,我们在末尾添加的单个项目不是地图,而是仅包含一个项目的集合。
所以对于你的查询:
RETURN [
{type:1, Orders:[{Price:10,Amount:100},
{Price:11,Amount:200},
{Price:12,Amount:300}]},
{type:2, Orders:[{Price:10,Amount:100},
{Price:11,Amount:**250**},
{Price:12,Amount:300}]}]
+
[{type:3, Orders:[{Price:10,Amount:100},
{Price:11,Amount:200},{Price:12,Amount:300}]}]
as **CombinedOrders**
应该做的伎俩。
或者你也许可以做得更清洁,像这样:
WITH [{type:1, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]},
{type:2, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]},
{type:3, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]}] as ExistingOrders,
{type:2, Order:{Price:11,Amount:50}} as NewOrder
RETURN ExistingOrders + [NewOrder];
现在好了,对于没有意义的部分。在您的示例中,您似乎想要修改集合内的地图。但是你有两张{type:2}
地图,你正在寻找将它们合并到你要求的输出中有一个{type:3}
地图的地图。如果您需要解除冲突地图条目并更改地图条目应该是什么,那么可能是cypher不是您进行此类查询的最佳选择。
答案 2 :(得分:0)
我明白了:
WITH [{type:1, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},Price:12,Amount:300}]},{type:2, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]},{type:3, Orders:[{Price:10,Amount:100},{Price:11,Amount:200},{Price:12,Amount:300}]}] as ExistingOrders,{type:2, Orders:[{Price:11,Amount:50}]} as NewOrder
RETURN
reduce(map=filter(p in ExistingOrders where not p.type=NewOrder.type),
x in [(filter(p2 in ExistingOrders where p2.type=NewOrder.type)[0])]|
CASE x
WHEN null THEN NewOrder
ELSE {type:x.type, Orders:[
reduce(map2=filter(p3 in x.Orders where not (p3.Price=(NewOrder.Orders[0]).Price)),
x2 in [filter(p4 in x.Orders where p4.Price=(NewOrder.Orders[0]).Price)[0]]|
CASE x2
WHEN null THEN NewOrder.Orders[0]
ELSE {Price:x2.Price, Amount:x2.Amount+(NewOrder.Orders[0]).Amount}
END+map2 )]} END+map) as CombinedOrders
...使用嵌套的Reduce函数。
因此,首先,它将订单列表与匹配type
组合在一起,列出了这些订单(实际上只有一个) with a匹配type
。对于后者ExistingOrders
(type
与NewOrder
匹配),它在嵌套Price
函数中与reduce
做类似的事情并组合不匹配{ {1}}匹配Price
s,在后一种情况下添加Price
。