有两种节点类型,Account
和Transfer
。 Transfer
表示Account
个节点之间资金的移动。 Transfer
个节点可以有任意数量的输入和输出节点。例如,三个Accounts
可以以任何他们喜欢的方式向其他16个Accounts
发送40美元(合计120美元),这样就可以了。
Transfer
对象不具有发送或接收的资金总和 - 这些资金仅存储在关系本身中。我想在cypher查询中计算并将其作为返回的Transfer
对象的一部分返回,不单独。 (类似于SQL JOIN)
我是Neo4j + Cypher的新手;到目前为止,我得到的问题是:
MATCH (tf:Transfer {id:'some_id'})
MATCH (tf)<-[in:IN_TO]-(in_account:Account)
MATCH (tf)-[out:OUT_TO]->(out_account:Account)
RETURN tf,in_account,in,out_account,out, sum(in.value) as sum_in, sum(out.value) as sum_out
如果我管理了这个数据库,我只是预先计算总和并将其存储在Transfer
属性中 - 但目前这不是一个选项。
tl;博士:我想在归档的sum_in
对象中存储sum_out
和tf
。
答案 0 :(得分:0)
当您使用SUM
之类的聚合时,您必须将聚合的别名保留在结果行之外,否则您将以单行总和结束。这可以帮助您获得更接近您想要的东西,包括动态属性赋值的解决方法:
CREATE (temp)
WITH temp
MATCH (tf:Transfer {id:'some_id'})
MATCH (tf)<-[in:IN_TO]-(in_account:Account)
MATCH (tf)-[out:OUT_TO]->(out_account:Account)
SET temp += PROPERTIES(tf)
WITH temp, SUM(in.value) AS sum_in, SUM(out.value) AS sum_out, COLLECT(in_account) AS in_accounts, COLLECT(out_account) AS out_accounts
SET temp.sum_in = sum_in
SET temp.sum_out = sum_out
WITH temp, PROPERTIES(temp) AS props, in_accounts, out_accounts
DELETE temp
RETURN props, in_accounts, out_accounts
您正在创建一个虚拟节点来保存属性,因为这是将动态属性分配给现有地图或地图相似的唯一方法,但该节点不会被提交到图表。此查询应返回:Transfer
属性的地图,其中包含输入和输出,以及内外帐户列表,以防您需要执行任何其他工作它们。
答案 1 :(得分:0)
Tore Eschliman的回答非常有见地,尤其是聚合别名的属性。
我想出了一个更具攻击性的解决方案,在这种情况下可行。
示例数据集:
height
查询:
CREATE
(a1:Account),
(a2:Account),
(a3:Account),
(tf:Transfer),
(a1)-[:IN_TO {value: 110}]->(tf),
(a2)-[:IN_TO {value: 230}]->(tf),
(tf)-[:OUT_TO {value: 450}]->(a3)
结果:
MATCH (in_account:Account)-[in:IN_TO]->(tf:Transfer)
WITH tf, SUM(in.value) AS sum_in
SET tf.sum_in = sum_in
RETURN tf
UNION
MATCH (tf:Transfer)-[out:OUT_TO]->(out_account:Account)
WITH tf, SUM(out.value) AS sum_out
SET tf.sum_out = sum_out
RETURN tf
请注意╒═══════════════════════════╕
│tf │
╞═══════════════════════════╡
│{sum_in: 340, sum_out: 450}│
└───────────────────────────┘
执行集联合(而不是执行多集/包联合的UNION
),因此我们在结果中不会有重复。
更新:正如Tore Eschliman在评论中指出的,这个解决方案将修改数据库。作为解决方法,您可以收集结果并在之后中止事务。