解决派对费用问题
简介
这个周六下午“沙发研讨会”的想法源于一个常见的情况,一群人各自为派对带来食物用品。
然后就到了每个人都必须为其他人支付欠款的时候(A欠B €€€,B欠C €€€,等等)。
人数越多,就越具有挑战性,有时会导致一些混乱的情况。我过去使用电子表格来解决这个等式,然后出现了图数据库和Neo4j。
设置
// 1. Initializing the Database
CREATE
(gaelle:Person {name: "Gaëlle"}),
(gregory:Person {name: "Gregory"}),
(mathilde:Person {name: "Mathilde"}),
(michel:Person {name: "Michel"}),
(yann:Person {name: "Yann"}),
(gaelle)-[:SPENT {amount: 100}]->(gaelle),
(gregory)-[:SPENT {amount: 35}]->(gregory),
(mathilde)-[:SPENT {amount: 67}]->(mathilde),
(michel)-[:SPENT {amount: 0}]->(michel),
(yann)-[:SPENT {amount: 85}]->(yann);
// 2. Adding the Debt Relationship
MATCH (p:Person)
WITH toFloat(count(p)) AS GuestsCount
MATCH (s:Person)
MATCH (t:Person)
MATCH (s)-[r:SPENT]-(s)
WHERE s <> t
AND r.amount <> 0
CREATE (t)-[:OWES_TO {amount: round(r.amount / GuestsCount * 100) / 100}]->(s);
// 3. Simplifying Mutual Debts
MATCH (s)-[r1:OWES_TO]->(t)
MATCH (t)-[r2:OWES_TO]->(s)
WHERE r1.amount - r2.amount > 0
// Create a new merged transaction...
CREATE (s)-[:OWES_TO {amount: round((r1.amount - r2.amount) * 100) / 100}]->(t)
// ...Then delete the previous ones
DELETE r1
DELETE r2;
问题
假设我们有五个人来参加我们的派对。他们的费用是
MATCH (n)-[r:SPENT]-(n)
RETURN n.name as Person, r.amount AS Expense
ORDER BY Person;
初始化数据库
以下Cypher查询将创建人员(节点)及其费用(使用自关联关系)
CREATE
(gaelle:Person {name: "Gaëlle"}),
(gregory:Person {name: "Gregory"}),
(mathilde:Person {name: "Mathilde"}),
(michel:Person {name: "Michel"}),
(yann:Person {name: "Yann"}),
(gaelle)-[:SPENT {amount: 100}]->(gaelle),
(gregory)-[:SPENT {amount: 35}]->(gregory),
(mathilde)-[:SPENT {amount: 67}]->(mathilde),
(michel)-[:SPENT {amount: 0}]->(michel),
(yann)-[:SPENT {amount: 85}]->(yann);
注意:费用可以存储为人员的属性。关系被优先使用,因为费用代表一个动作(用动词描述),而不是人员的特征。

MATCH (n)-[r:SPENT]-(m) RETURN *;
添加债务关系
以下Cypher查询将在两个人之间添加一个关系,以指示第一个人欠第二个人多少钱。
MATCH (p:Person)
WITH toFloat(count(p)) AS GuestsCount
MATCH (s:Person)
MATCH (t:Person)
MATCH (s)-[r:SPENT]-(s)
WHERE s <> t
AND r.amount <> 0
CREATE (t)-[:OWES_TO {amount: round(r.amount / GuestsCount * 100) / 100}]->(s);

简化互欠债务
就像现实生活中一样,如果两个人互相欠钱,我们将两个交易合并成一个。
这是使用以下Cypher查询完成的
MATCH (s)-[r1:OWES_TO]->(t)
MATCH (t)-[r2:OWES_TO]->(s)
WHERE r1.amount - r2.amount > 0
// Create a new merged transaction...
CREATE (s)-[:OWES_TO {amount: round((r1.amount - r2.amount) * 100) / 100}]->(t)
// ...Then delete the previous ones
DELETE r1
DELETE r2;
输出报告
Set 6 properties, deleted 12 relationships, created 6 relationships.

MATCH (n)-[r]-(m) RETURN *;
获取账单
我们最后的Cypher查询总结了每个人的债务
MATCH ()-[r:OWES_TO]->()
WITH
startNode(r).name AS Debitor,
endNode(r).name AS Creditor,
r.amount AS Amount
RETURN Debitor, Amount, Creditor
ORDER BY Debitor, Amount;
此页面是否有帮助?