neo4j图中节点的扩展层

k2fxgqgv  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(104)

我有两个节点类型“人员”和“公司”。还有一种关系称为“股东”,可以是个人对公司或公司对公司(因为公司也可以持有其他公司的股份)。Shareholder关系有三个属性:“持股开始日期”、“持股结束日期”、“股份数”。
我有一个查询,它需要公司名称(称之为“ABC”),以及提供一个日期(例如:'2021-07- 23'),并且查询返回在日期'2021-07-23'是c的股东的所有人/公司节点(即持股_开始_日期< 2021-07-23 <持股_结束_日期)。它还根据“number_of_shares”计算百分比。
工作查询如下:

MATCH (c:Company {name:”ABC”})<-[r:Shareholder]-(s)
WHERE R.shareholding_start_date <= Date(“2021-07-23”) 
   AND r.shareholding_end_date >= DATE(“2021-07-23”)
WITH c, 
collect(s) as shareholders, 
collect(r) as rels, 
sum(r.number_of_shares) AS totalShares
UNWIND range(0, size(rels) - 1) AS I
RETURN shareholders[i].name AS shareholder, 
100.0 * rels[i].number_of_shares/totalShares as percentTotalShares

字符串
我希望扩展它,以便它也显示股东的股东,直到可以在查询中定义的某个层限制(例如,假设3)。因此,在上面的示例中,查询将返回公司“ABC”的所有股东,这些股东可能是“Person”或“Company”节点类型。在“ABC”的股东是“公司”节点的情况下,我基本上想重复相同的代码,并列出他们的所有股东,沿着在该公司的持股百分比。这应该继续,直到我们达到极限(即(3)第三章。

drnojrws

drnojrws1#

假设

1.日期约束被应用于到指定公司(“ABC”)的每个路径中的所有关系。
1.如果当前仍持有股份,则结束日期属性不存在。
1.如果实体仅出售其给定购买中的一部分股份,则会添加结束日期属性,将股份数减少为已出售的股份数,并使用剩余股份创建具有相同开始日期的新关系。(这在我的回答中没有实现,因为用例不出售任何股份)。
1.在计算公司的totalShares时,也会强制执行日期约束。
1.公司可以持有自己的部分股份。
1.在parameters$targetDate$company中传递目标日期和公司名称。

数据模型

为了便于阅读,我简化了数据模型中的名称:

(:Person|Company {name})-[:HOLDS {start, end, shares}]->(:Company {name})

字符串

密码查询

以下是实现您的用例的一种方法:

WITH DATE($targetDate) AS targetDate

// Find all paths up to length 3 involving the specified company, on the target date.
MATCH ()-[rs:HOLDS*..3]->(:Company {name: $company})
WHERE ALL(r IN rs WHERE r.start <= targetDate AND (r.end IS NULL OR targetDate <= r.end))

// Collect the distinct HOLD relationships in the paths for each company.
WITH targetDate, ENDNODE(rs[0]) AS c, COLLECT(DISTINCT rs[0]) AS rels

// Calculate total number of shares owned by each company in the paths, on the target date
UNWIND rels AS rel
WITH c, rels, SUM(rel.shares) AS totalShares

// Return a company, a shareholder, and the percentage of that company owned by the shareholder on the target date.
UNWIND rels AS rel
WITH totalShares, c.name AS company, STARTNODE(rel).name AS holder, SUM(rel.shares) AS shares
RETURN company, holder, 100.0*shares/totalShares AS pct

测试数据

CREATE (p1:Person {name: 'John'}),
       (p2:Person {name: 'Dave'}),
       (p3:Person {name: 'Alice'})

CREATE (c1:Company {name: 'Comp1'}),
       (c2:Company {name: 'Comp2'}),
       (c3:Company {name: 'Comp3'}),
       (c4:Company {name: 'ABC'})

CREATE (p1)-[:HOLDS {start: date('2018-01-01'), end: date('2022-12-31'), shares: 1000}]->(c1)
CREATE (c2)-[:HOLDS {start: date('2020-01-01'), end: date('2025-12-31'), shares: 750}]->(c1)
CREATE (p3)-[:HOLDS {start: date('2019-01-01'), end: date('2022-12-31'), shares: 800}]->(c3)
CREATE (c1)-[:HOLDS {start: date('2016-07-01'), end: date('2023-12-31'), shares: 800}]->(c4)

// Dave bought 500 shares of Comp1, and later bought 250 more.
// Then he sold 125 shares from the second batch on '2023-06-30' and still has the remaining 125 shares.
CREATE (p2)-[:HOLDS {start: date('2020-01-01'), end: date('2023-12-31'), shares: 500}]->(c1)
CREATE (p2)-[:HOLDS {start: date('2023-01-01'), end: date('2023-06-30'), shares: 125}]->(c1)
CREATE (p2)-[:HOLDS {start: date('2023-01-01'), shares: 125}]->(c1)

// ABC and Comp2 own shares of each other
CREATE (c2)-[:HOLDS {start: date('2017-01-01'), end: date('2023-12-31'), shares: 700}]->(c4)
CREATE (c4)-[:HOLDS {start: date('2016-07-01'), shares: 500}]->(c2)

// Comp1 holds (and continues to hold) some of its own shares
CREATE (c1)-[:HOLDS {start: date('2021-01-01'), shares: 500}]->(c1)

结果

使用$targetDate =“2023-07-21”和$company =“ABC”:

╒═══════╤═══════╤══════════════════╕
│company│holder │pct               │
╞═══════╪═══════╪══════════════════╡
│"ABC"  │"Comp2"│46.666666666666664│
├───────┼───────┼──────────────────┤
│"ABC"  │"Comp1"│53.333333333333336│
├───────┼───────┼──────────────────┤
│"Comp2"│"ABC"  │100.0             │
├───────┼───────┼──────────────────┤
│"Comp1"│"Comp2"│40.0              │
├───────┼───────┼──────────────────┤
│"Comp1"│"Dave" │33.333333333333336│
├───────┼───────┼──────────────────┤
│"Comp1"│"Comp1"│26.666666666666668│
└───────┴───────┴──────────────────┘

匹配图

下面是上面查询的第一个MATCH/WHERE对找到的路径图。
x1c 0d1x的数据
以下是可视化查询(上述查询的前3个子句的一个小变体):

WITH DATE($targetDate) AS targetDate
MATCH (h)-[rs:HOLDS*..3]->(c:Company {name: $company})
WHERE ALL(r IN rs WHERE r.start <= targetDate AND (r.end IS NULL OR targetDate <= r.end))
RETURN *

相关问题