在过去的30年里,我有大约200家实体投资了一家公司。我一直在追踪他们随着时间的推移贡献了多少钱。我的数据库将在Neo4J中。
到目前为止,在我的图表上,我有(1)200个节点代表已投资的200个实体,(2)1个节点代表他们投资的单个公司。
我认为两种选择可以代表资本注入:
我明确地创建了1,500个节点,代表每个初始资本注入,资本增加等。节点捕获有关美元金额等变化的信息。然后我的图表大致为(e:Entity)-[:PROVIDES]->(f:Financing {amount: {value}, year: {2010}})-[:PROVIDES]->(t:Target)
。在某种程度上,我发现这个更清洁,更容易进行分析,但这将是一个更大的图表,并且PROVIDES关系不是特别有见地。
我更直接地代表这1500个融资轮次,作为200个实体和目标公司之间的关系
(e:Entity)-[:FINANCING {amount: {value}, year: {2010}}]->(t:Target)
。在这种情况下,我对后来如何处理分析或者在实体X和目标公司之间说出50个融资关系是否有意义有点不确定。
我想做的分析类型包括:(1)在2004年产生目标实体所有权,(2)通过实体X等产生目标公司股权的随时间演变
您建议将什么作为架构的解决方案?我知道Neo4J是架构可选的,但我怀疑节点和关系之间的这种选择很重要。
非常感谢!
干杯
答案 0 :(得分:4)
对于经常被查询但数量有限但可能有限的数据(如年,特别是30年)的数据,如果移动{{1},很多时候你会看到更好的性能将属性放到一个单独的节点上,这样就可以快速对连接到它的所有节点进行分组并获取其year
属性一次,而不是基本上为它重新创建属性索引。这需要在这种情况下添加year
节点,以便您可以将:Financing
,:Entity
,和 :Target
节点连接到相同的交易记录。
所以你的数据模型就像:
:Year
从而允许您按年份值对数据进行切片,而无需扫描所有节点的属性。您还可以在(:Entity) - [:PROVIDES] -> (:Financing {amount: x}) - [:PROVIDES] -> (:Target)
(:Financing) - [:OCCURRED_IN] -> (:Year {year: 1999})
上添加属性索引,但是将有限的离散属性(如年份)建模为单独的路径可以让您更轻松地扩展图形,并使查询性能更易于实现。
不管怎样,你肯定会想要一个:Financing(year)
节点。除了在结果中返回之外,关系上的属性很少用于任何事情;它们无法编入索引,因此它们总是需要进行属性扫描才能获得结果,如果你有很多关系,那么可以快速加起来。
Starter查询(假设所有权是提供给定点的总金额的百分比),以便在2004年底按实体获得%所有权:
:Financing
每年提供实体2(任意标识符)的融资比例:
MATCH (t:Target {id: 1})
WITH t
MATCH (y:Year)
WHERE y.year <= 2004
WITH t, y
MATCH (y) <- [:OCCURRED_IN] - (f:Financing) - [:PROVIDED] -> (t)
WITH f, f.amount as amt
WITH COLLECT({f: f, amt: amt}) AS rows, SUM(amt) AS total
UNWIND rows AS row
WITH row.f as f, row.amt as amt, total
MATCH (e:Entity) - [:PROVIDED] -> (f)
WITH e, SUM(amt) AS part, total
RETURN e, part/total * 100 AS percentage