Neo4j 版本控制与时间的关系 属性

Neo4j Versioning Relationships with Time Property

我正在尝试为树结构的版本控制系统建模。这是示例:

因此,在版本 2 中,我将 B 移动到 D。实际上,我现在可以通过创建一个版本节点并将其关联到所有包含的节点来实现这一点,并在每个 [=] 上给予时间 属性 53=]关系。所以图表将如下所示:

版本 1

MERGE (a:COMPONENT {name:'a'})
MERGE (b:COMPONENT {name:'b'})
MERGE (c:COMPONENT {name:'c'})
MERGE (d:COMPONENT {name:'d'})
MERGE (e:COMPONENT {name:'e'})
MERGE (version:VERSION {createdOn:'16-4-2015 12:17:00'})
MERGE (version)-[:CONTAINS]->(a)
MERGE (version)-[:CONTAINS]->(b)
MERGE (version)-[:CONTAINS]->(c)
MERGE (version)-[:CONTAINS]->(d)
MERGE (version)-[:CONTAINS]->(e)
MERGE (a)<-[:BELONGS_TO {createdOn:'16-4-2015 12:17:00'}]-(b)
MERGE (a)<-[:BELONGS_TO {createdOn:'16-4-2015 12:17:00'}]-(c)
MERGE (d)<-[:BELONGS_TO {createdOn:'16-4-2015 12:17:00'}]-(e)
RETURN *

版本 2

MERGE (a:COMPONENT {name:'a'})
MERGE (b:COMPONENT {name:'b'})
MERGE (c:COMPONENT {name:'c'})
MERGE (d:COMPONENT {name:'d'})
MERGE (e:COMPONENT {name:'e'})
MERGE (version:VERSION {createdOn:'28-5-2015 13:00:00'})
MERGE (version)-[:CONTAINS]->(a)
MERGE (version)-[:CONTAINS]->(b)
MERGE (version)-[:CONTAINS]->(c)
MERGE (version)-[:CONTAINS]->(d)
MERGE (version)-[:CONTAINS]->(e)
MERGE (a)<-[:BELONGS_TO {createdOn:'28-5-2015 13:00:00'}]-(c)
MERGE (d)<-[:BELONGS_TO {createdOn:'28-5-2015 13:00:00'}]-(b)
MERGE (d)<-[:BELONGS_TO {createdOn:'28-5-2015 13:00:00'}]-(e)
RETURN *

我使用 MERGE 子句导入我的树结构,因为我想重用以前版本的节点(如果这些节点与新版本引用的节点相同)。这样做的原因是我不想丢失到树结构中每个节点的映射。

我的查询是这样的:

MATCH (version:VERSION)-[:CONTAINS]->(component:COMPONENT)
WHERE version.createdOn = '28-5-2015 13:00:00'
OPTIONAL MATCH
(component)-[rels:BELONGS_TO*]->(componentParents)
WHERE ALL(rel IN rels WHERE rel.createdOn = '28-5-2015 13:00:00')
RETURN *

事实是,我的方法是有效的,但我担心一旦树的版本变得非常大(假设 10,000 个版本,尽管这可能不是真实的场景)时的性能。以我的理解,它需要比较许多具有不同 'createdOn' 值的关系才能获得所选版本的正确路径。 我的问题是,我的担心是否正确?树结构图这样建模好不好?如果不是,您如何建议更好的模型?

提前致谢,如有任何想法,我们将不胜感激!

版本控制不是一门精确的科学,尤其是在图形和您的用例中。根据您的需要,有多种方法可以做到这一点。

当图表的大小变大时,您的模型可能会对性能产生影响。过滤关系或节点属性(未为关系编制索引)是非常昂贵的操作。通常,关系会驱使您找到图表并为其添加语义。

有一种常见的模式可以表示节点的状态,例如您将有一个唯一节点代表您的 Component 和多个 ComponentState 节点代表 组件随时间的状态.

在某些 Ascii-Art 中,您将拥有:

(Component)-[:LAST_STATE]->(ComponentState {version:2})
-[:PREVIOUS_STATE]->(ComponentState {version: 1})

图片中:

这些 ComponentState 节点将与 belongs_to 组件节点建立关系。

我用你的例子创建了一个小的 Neo4j 控制台:

http://console.neo4j.org/r/4trq7i

如果你想知道 Instant 的图(见这里版本)1,你只需要匹配此时的 State 组件并遍历 BELONGS_TO 关系:

MATCH (n:ComponentState {version: 1})
MATCH (n)-[:BELONGS_TO]->(parent)
RETURN n.name, parent.name

哪个 return 以下 :

n.name  parent.name
b   a
c   a
e   d

因此对于您的用例,您可以在此处添加时间代替版本或使用 TimeTree

如果需要,您可能还想创建组件状态之间的关系来代替组件状态到组件。

希望对您有所帮助。