嗨,我想在neo4j中表达以下关系,我想找到最佳方式,或者可能不是最佳方式,但我可以通过不同的方式做到这一点。案件如下:
时间段是一个非常重要的质量,所以在某种程度上它是模型的一等公民。我想知道的是,如果我将其表达为Neo4J模型,我可以采用以下几种方法:
方法1。
方法2。
然后关系会是这样的。 * Animal --FOR - > Period --Assigned - > CAGE
模型应该能够回答什么问题。
如果动物在同一个笼子里以相同的时间间隔放在一起,我们应该能够收集信息。问题是,一个开放空间可能包含许多笼子,因此我们想知道两只动物是否曾在同一个开放空间内共同定位。
如果每个特定时间段都有一个唯一的(因此共享的)Period
节点,则方法2是不实际的,因为该节点可能存在任意数量的ASSIGNED
关系,并且您将无法分辨哪些关系属于哪种动物(在每种关系中没有冗余地存储动物ID)。
使用方法1,让我们假设这个数据模型(其中A
表示:“动物被分配到位于空间中的笼子”,而B
表示:“动物直接分配到空间 - 而不是笼子”) :
A. (:Animal)-[:ASSIGNED {start: 123, end: 789}]->(:Cage)-[:LOCATED_IN]->(:Space)
B. (:Animal)-[:ASSIGNED {start: 234, end: 777}]->(:Space)
获取同时占据同一笼子的所有动物的信息:
MATCH
(a1:Animal)-[r1:ASSIGNED]->(c:Cage),
(a2:Animal)-[r2:ASSIGNED]->(c)
WHERE ID(a1) < ID(a2) AND r1.start < r2.end AND r2.start < r1.end
RETURN c, a1, r1, a2, r2
获取同时占用同一空间的所有动物的信息:
MATCH
(a1:Animal)-[r1:ASSIGNED]->()-[:LOCATED_IN*0..1]->(s:Space),
(a2:Animal)-[r2:ASSIGNED]->()-[:LOCATED_IN*0..1]->(s)
WHERE ID(a1) < ID(a2) AND r1.start < r2.end AND r2.start < r1.end
RETURN s, a1, r1, a2, r2
笔记:
ID(a1) < ID(a2)
测试用于避免重复结果(动物1和2,然后再次为2和1)。r1.start < r2.end AND r2.start < r1.end
测试用于检测重叠的占用时间。(x)-[:LOCATED_IN*0..1]->(y)
语法匹配长度为0的可变长度路径(在这种情况下,没有LOCATED_IN
关系,x
与y
相同)或长度为1。