我尝试连接Spring Data Neo4j中的各种节点类型。 是否建议(或不鼓励)对链接不同节点类型的类似关系使用相同的关系类型?
例如,如果我们有一个Driver类(注释为@NodeEntity
),我们想要模拟驱动程序可以驱动不同车辆的事实,例如汽车和自行车,这是更好的:
@RelatedTo(elementClass = CarNode.class, type = "drives", direction = OUTGOING)
private Set<Car> cars;
@RelatedTo(elementClass = BikeNode.class, type = "drives", direction = OUTGOING)
private Set<Bike> bikes;
因为司机可以驾驶不同类型的车辆,或者我们应该在关系中指出车辆的类型:
@RelatedTo(elementClass = CarNode.class, type = "drivesCar", direction = OUTGOING)
private Set<Car> cars;
@RelatedTo(elementClass = BikeNode.class, type = "drivesBike", direction = OUTGOING)
private Set<Bike> bikes;
第一种可能性似乎在语义上更正确,但在整个图中使用特定关系可以允许更快的遍历(不需要测试节点类型)似乎是合乎逻辑的。
如果通用关系更好,那么如何使用Cypher查询获得一组汽车或仅一组自行车?
谢谢!
答案 0 :(得分:2)
一般来说,建议对关系类型进行详细说明。
主要原因是您的查询会变得更便宜。例如,假设您想要查询给定的驱动程序他开的所有自行车。如果是通用关系类型drives
,则会在Cypher中解决:
start d=node:driver(name=<driverName>)
match (d)-[:drives]->(vehicle)
where vehicle.__type__ = 'Bike'
return vehicle
而在详细关系类型的情况下:
start d=node:driver(name=<driverName>)
match (d)-[:drivesBike]->(bike)
return bike
第二个更便宜,因为你没有穿越非自行车。在第一种情况下,你对遍历贪婪,然后应用过滤器。
答案 1 :(得分:2)
为Stefan的回答添加一点:您实际上可能会考虑同时使用通用drives
和 drivesBike
&amp; drivesCar.
在某些情况下,您可能只想检索一个人驾驶的所有车辆,为此......您有drives.
如果您想要所有骑自行车的人,那么drivesBike.
如果您同时具有特定和通用关系,则可以以两种方式进行最佳查询,并且具有额外关系并不会真正影响您的数据库大小(尽管它在代码方面添加了一些内容,以添加两个关系链接。请记住,如果您只有特定的驱动程序关系,则会有一些OR查询,所有驱动程序类型都被调出,并且每次添加新的车辆类型时都需要更新查询。例如,拥有通用drives
关系会更方便。
实际上在Graph Databases一书中提到了这个想法。您可以在那里阅读有关此模式的更多信息。