Neo4j spring数据设计

qni6mghb  于 2023-10-18  发布在  Spring
关注(0)|答案(1)|浏览(132)

我目前正在开始使用Neo4j,我想创建一个基本的社交媒体应用程序来了解更多。
我正在使用spring data neo4j来连接我的spring Boot 后端和neo4j。
我的应用程序非常简单,它只是让一个用户跟随另一个用户。
使用Cypher查询,一切都很简单。但我不想写任何明确的查询,并使用仓库来获取我想要的数据。
这是我的User类

@Node
    public class User {
    @Id
    private Long id;
    private String name;

    @Relationship(type="FOLLOWS", direction = Relationship.Direction.INCOMING)
    private HashSet<User> followsReceived = new HashSet<>();

    @Relationship(type="FOLLOWS", direction = Relationship.Direction.OUTGOING)
    private HashSet<User> followsGiven = new HashSet<>();
}

这是我的Follows课程

@RelationshipProperties
public class Follow {
    @Id @GeneratedValue
    private Long id;

    @TargetNode
    private User endNode;
}

这个设计有意义吗?
我现在有点困惑,因为例如,如果我想找到一个特定的用户遵循的用户,我得到了一个递归结构,尽管实现了分页,但几乎加载了整个数据库。
有人可以请建议我一个更干净的设计,其中获得用户我遵循和用户谁遵循我不会加载整个数据库。
如果可能的话,我想在没有@Query注解的情况下实现它。

1u4esq0p

1u4esq0p1#

首先,@RelationshipProeprties类是不需要的,在你的例子中也没有用到。您必须将其作为泛型类型放入User's关系定义中。但是由于您没有向它添加任何属性,因此您可以 )跳过它。
关于你的主要问题:Spring Data Neo4j默认加载从域模型Angular 可访问的所有内容。UserUser之间的这种循环依赖关系(在您正在工作的域中是有意义的)预计将在此场景中结束。旧版本的SDN在获取数据时创建了2跳的虚拟屏障,如果没有参数化以加载更多。在较新的版本中,SDN提升了投影的概念,以更细粒度地定义这些障碍。(https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#projections.interfaces)
考虑到加载User及其所有追随者的用例,您可以考虑定义一个投影,如

interface UserProjection {
 String getName();
 Set<Follower> getFollowsReceived();
 Set<Follower> getFollowsGiven();
}

interface Follower {
 String getName();
 // no relationships defined here to break the circle
}

然后在仓库中像这样使用它:

interface UserRepository extends Neo4jRepository<User, Long> {
  UserProjection findByName(String name);
}

(从我的头上写的,请查看链接文档以了解更多细节)
这里重要的一点是,您只引用了“根”投影(UserProjection)中的另一个投影接口(Follower)。如果您引用任何已定义的实体(@Node注解),SDN将返回到循环加载机制,以再次找到所有可访问的内容。

  • 在标识符周围使用 Package 器可以为您提供性能优势,因为Spring Data Neo4j使用此信息来确定数据库中是否已经存在关系。但要做到这一点,你必须在你的Sets中使用它,而不是与其他Users的直接关系。

相关问题