2016-10-29 174 views
0

有兩種節點類型,AccountTransfer。 A Transfer表示資金在Account節點之間的移動。節點可以有任意數量的輸入和輸出節點。例如,三個Accounts可能會以任何方式向其他16個Accounts發送40美元(合計120美元),並且它可以工作。Neo4j/Cypher:返回節點本身內節點之間關係值的總和

Transfer對象沒有發送或接收的資金總和 - 它們只存儲在關係本身中。我想在密碼查詢中計算這個值,並將其作爲返回的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_insum_out在返回tf對象。

回答

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的屬性的Map,包含輸入和輸出,以及輸入和輸出帳戶的列表,以防您需要對其進行任何額外的工作。

+0

h/t到Gábor的錯字接收。 –

0

Tore Eschliman的回答很有洞察力,特別是在聚合別名的屬性上。

我想出了一個更駭人的解決方案,可以在這種情況下工作。

實施例的數據集:

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執行一組聯合(相對於UNION ALL,其執行多集/ bag union),因此我們不會在結果中有重複。

更新:正如Tore Eschliman在評論中指出的,該解決方案將修改數據庫。作爲一種解決方法,您可以收集結果並在事後中止交易。

+0

這將永久性地改變':Transfer'節點。 –

+0

好點。我試圖解決它,但似乎這不是解決問題的好方向。我現在對解決方案非常感興趣,但是我無法使用示例數據集處理查詢:如果使用'DELETE temp',結果行將充滿空值和空值集合。如果你刪除'DELETE temp',它就像一個魅力。 (我正在使用Neo4j 3.0.4。) –

+0

你是絕對正確的,我忘了最重要的部分。您必須在刪除之前將「PROPERTIES(n)」指定給另一個別名,否則它將消失。 –