GraphGists

简介

这个周六下午“沙发研讨会”的想法源于一个常见的情况,一群人各自为派对带来食物用品。

然后就到了每个人都必须为其他人支付欠款的时候(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);

注意:费用可以存储为人员的属性。关系被优先使用,因为费用代表一个动作(用动词描述),而不是人员的特征。

01 expenses
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);
02 debts

简化互欠债务

就像现实生活中一样,如果两个人互相欠钱,我们将两个交易合并成一个。

这是使用以下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.
03 one transaction
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;

结论

只有第一个查询需要修改以适应您自己的情况。

享受您的派对!:-)


由Michel CARADEC创建 - LinkedIn