Neo4j / Cypher:返回节点本身内节点之间关系的值之和

时间:2016-10-29 02:06:20

标签: neo4j cypher

有两种节点类型,AccountTransferTransfer表示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_outtf

2 个答案:

答案 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在评论中指出的,这个解决方案将修改数据库。作为解决方法,您可以收集结果并在之后中止事务。