从边缘获取权重的百分比

huangapple go评论68阅读模式
英文:

Getting weights as percentages from edges

问题

我有两种节点类型 "Person" 和 "Company"。还有一个名为 "Shareholder" 的关系,可以从个人到公司,也可以从公司到公司(因为公司也可以持有其他公司的股份)。"Shareholder" 关系有三个属性 "shareholding_start_date"、"shareholding_end_date"、"number_of_shares"。

我想要能够按名称查询一个公司(称为 c),同时提供一个日期(例如 '2021-07-23'),查询应该返回在日期 '2021-07-23' 持有 c 股份的所有个人/公司节点(即 shareholding_start_date < 2021-07-23 < shareholding_end_date)。我还想根据 'number_of_shares' 计算百分比。

举个例子,假设有一家名为 XYZ 的公司,我想知道在 2022-03-15 这一天它的所有股东。假设 ABC 在这一天有三个股东,分别是 ABC、DEF、GHI(这些可以是个人节点或公司节点)。ABC 持有 30 股,DEF 持有 50 股,GHI 持有 120 股。

查询应该类似于以下内容(显然这不是 Cypher,但我无法以其他方式表达!):

Company.name = "XYZ"
and Shareholder.shareholding_start_date <= 2022-03-15
and Shareholder.shareholding_end_date >= 2022-03-15

返回结果类似于:

ABC 15%,DEF 25%,GHI 60%
英文:

I have two node types "Person" and "Company". There is also a relationship called "Shareholder", which can be from Person to Company or Company to Company (as companies can also hold shares in other companies). The Shareholder relationship has three properties "shareholding_start_date", "shareholding_end_date", "number_of_shares".

I want to be able to query a Company (call it c) by name, as well as provide a date (e.g. '2021-07-23'), and the query should return all Person/Company nodes that are shareholders of c at the date '2021-07-23' (i.e. shareholding_start_date < 2021-07-23 < shareholding_end_date). I also want to calculate the percentage based on 'number_of_shares'.

As an example, let's say there is a company called XYZ, and I want to know all it's shareholders on 2022-03-15. Suppose ABC has three shareholders ABC, DEF, GHI on this day (these can be either Person or Company nodes). ABC holds 30 shares, DEF holds 50 shares, GHI holds 120 shares.

The query should be something like this (obviously this is not cypher, but I'm unable to express it in any other way!):

Company.name = &quot;XYZ&quot;
and Shareholder.shareholding_start_date &lt;= 2022-03-15
and SHareholder.shareholding_end_date &gt;= 2022-03-15

Returns something like:

ABC 15%, DEF 25%, GHI 60%

答案1

得分: 2

匹配 (c:公司 {名称:&quot;ABC&quot;})&lt;-[r:股东]-(s)
其中 r.shareholding_start_date &lt;= Date(&quot;2022-03-15&quot;) 
   AND r.shareholding_end_date &gt;= DATE(&quot;2022-03-15&quot;)
WITH c, 
    收集(s) as 股东, 
    收集(r) as 关系, 
    总数(r.number_of_shares) AS 总股数
展开 范围(0, 大小(关系) - 1) AS i
返回 股东[i].名称 AS 股东, 
    100.0 * 关系[i].numberOfShares/总股数 as 百分比总股数

对于请求中要求显示距离目标公司的股东的股东的情况,可以使用以下方法。

匹配 p=(c:公司 {名称:&quot;ABC&quot;})&lt;-[r:股东*1..3]-(持有人)
WHERE 所有(持有 IN 关系(p) WHERE 持有.shareholding_start_date &lt;= Date(&#39;2022-03-15&#39;) &lt;= 持有.shareholding_end_date) 
WITH 
   长度(p) - 1 AS 距离目标公司的距离, 
   节点(p)[-2].名称 AS 公司名称,
   持有人, 
   关系(p)[-1].number_of_shares AS 持有股数
WITH 
   距离目标公司的距离,
   公司名称,
   收集(独特 {股东: 持有人.名称, 持有股数: 持有股数}) as 股东
WITH 
   距离目标公司的距离, 
   公司名称, 
   股东,
   减少(acc=0, 公司 IN 股东 | acc + 公司[&#39;numberOfShares&#39;]) AS 总股数
返回 
   距离目标公司的距离, 
   公司名称, 
   减少(acc=[], 公司 IN 股东 | acc + 公司{.*, 百分比总股数:100.0 * 公司[&#39;numberOfShares&#39;]/总股数}) AS 股东
按距离目标公司的距离, 公司名称排序
英文:
MATCH (c:Company {name:&quot;ABC&quot;})&lt;-[r:Shareholder]-(s)
WHERE r.shareholding_start_date &lt;= Date(&quot;2022-03-15&quot;) 
   AND r.shareholding_end_date &gt;= DATE(&quot;2022-03-15&quot;)
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].numberOfShares/totalShares as percentTotalShares

For more examples of percent of total in Neo4j, see this blog post. https://medium.com/neo4j/kickstart-your-transition-from-sql-analytic-and-window-functions-to-neo4j-987d67f7fdb4

To show shareholders of shareholders to an arbitrary distance from your target company as requested in the comment, you might use this approach.

MATCH p=(c:Company {name:&quot;ABC&quot;})&lt;-[r:Shareholder*1..3]-(holder)
WHERE all(holding IN relationships(p) WHERE holding.shareholding_start_date &lt;= Date(&#39;2022-03-15&#39;) &lt;= holding.shareholding_end_date) 
WITH 
   length(p) - 1 AS distanceToTargetCompany, 
   nodes(p)[-2].name AS companyName,
   holder, 
   relationships(p)[-1].number_of_shares AS number_of_shares
WITH 
   distanceToTargetCompany,
   companyName,
   collect(DISTINCT {shareHolder: holder.name, numberOfShares: number_of_shares}) as shareHolders
WITH 
   distanceToTargetCompany, 
   companyName, 
   shareHolders,
   reduce(acc=0, company in shareHolders | acc + company[&#39;numberOfShares&#39;]) AS totalShares
RETURN 
   distanceToTargetCompany, 
   companyName, 
   reduce(acc=[], company in shareHolders | acc + company{.*, percentTotal:100.0 * company[&#39;numberOfShares&#39;]/totalShares}) AS shareHolders
ORDER BY distanceToTargetCompany, companyName

huangapple
  • 本文由 发表于 2023年7月3日 10:15:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76601502.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定