springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

背景

依赖

springboot版本 2.7.10
本地neo4j安装的版本:4.4.19

依赖如下:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>

springboot整合neo4j官网地址:Accessing Data with Neo4j

遇到的问题:

按照官网向导本地运行后,得不到正确的关系

neo4j得到的数据如下:
在这里插入图片描述

            greg = personRepository.findByName(greg.getName());
            greg.worksWith(roy);
            greg.worksWith(craig);
            personRepository.save(greg);

            roy = personRepository.findByName(roy.getName());
            roy.worksWith(craig);
            // We already know that roy works with greg
            personRepository.save(roy);
            log.info("Lookup each person by name...");
            team.stream().forEach(person -> log.info(
                    "\t" + personRepository.findByName(person.getName()).toString()));

上面代码设置了greg的同事是roy,但是查询roy的同事确无法得到greg。
在这里插入图片描述

问题原因分析过程

参考资料1:

首先从官方github找相关issue,有人遇到同类问题,并得到回复如下(问题连接地址:https://stackoverflow.com/questions/68472313/spring-data-neo4j-6-relationship-undirected)。
在这里插入图片描述

也就是说在早期版本,我们可以在关系这里设置UNDIRECTED属性,实现数据间的双向关系。但是后来出于特别的考虑,Neo4j中的关系都是带有方向的关系,不再支持UNDIRECTORY这个属性(Neo4j-OGM支持?)

参考资料2:

官方示例代码在Person实体中也写了注释,大意和上述一致,而且给了连接(https://dzone.com/articles/modelling-data-neo4j)

   /**
     * Neo4j doesn't REALLY have bi-directional relationships. It just means when querying
     * to ignore the direction of the relationship.
     * https://dzone.com/articles/modelling-data-neo4j
     */
    @Relationship(type = "TEAMMATES",direction = Relationship.Direction.INCOMING)
    public Set<Person> teammates;

在这个连接中主要介绍了directed relationships 和 bidirectional relationships之间的区别及具体使用场景。

得到的核心信息如下:
在这里插入图片描述

这里引入了Cypher语法,也就是通过这些语法能够在neo4J中进行增删改查。通过模仿+实践得到结果如下:

MATCH (p1:Person)-[r:TEAMMATES]-(p2:Person) where p1.name = 'Roy' RETURN p2

在这里插入图片描述

此图结果表明,通过 - 查询是忽略关系方向的,能够得到roy的同事有Greg

MATCH (p1:Person)<-[r:TEAMMATES]-(p2:Person) where p1.name = 'Roy' RETURN p2

在这里插入图片描述

此图结果表明,通过 -> 查询是带有关系方向的,得不到roy的同事有Greg

解决办法

自定义查询语句,使用-查询忽略方向即可,修改如下

  @Query("MATCH (p1:Person)-[r:TEAMMATES]-(p2:Person) where p1.name = $name RETURN p2")
    List<Person> findByTeammatesName(String name);

按照官网demo的打印依然无法得到预期结果,因为数据库中虽然支持查询双向关系,但是并不能自动关联到java的Person对象的teammates中,所以我这里手动查询关系,再把关系设置到java实体中并打印即可。
在AccessingDataNeo4jApplication中修改如下

         log.info("-------------Lookup each person by name from neo4j...");
            team.forEach(p -> {
                List<Person> teammatesName = personRepository.findByTeammatesName(p.getName());
                p.setTeammates(new HashSet<>(teammatesName));
                log.info("\t" + p.toString());
            });

验证

再次运行程序,得到正确结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值