首页 > 解决方案 > Spring Neo4j @Query 在后续调用 .findOne 之前不会填充相关实体

问题描述

我有以下 Cypher,它在 Neo4j 浏览器中正常工作并按预期返回所有相关实体:

MATCH (cmp:Competition)-[:COMPETITION_COUNTRY]-(cc:Country)
WHERE ID(cmp)=16860

MATCH (cmp)-[:COMPETITION]-(s:Season)<-[:SEASON]-(f:Fixture)
WHERE s.yearStart=2019

MATCH (f)-[:HOME_TEAM]-(ht:Team)-[:TEAM_COUNTRY]-(htc:Country)
MATCH (f)-[:HOME_TEAM]-(at:Team)-[:TEAM_COUNTRY]-(atc:Country)

RETURN cmp, s, f, ht, at, htc, atc
ORDER BY f.matchDate DESC, ht.name DESC

我有这个Neo4jRepository函数如下:

@Query("MATCH (cmp:Competition)-[:COMPETITION_COUNTRY]-(cc:Country)\n" +
        "WHERE ID(cmp)={0}\n" +
        "\n" +
        "MATCH (cmp)-[:COMPETITION]-(s:Season)<-[:SEASON]-(f:Fixture)\n" +
        "WHERE s.yearStart={1}\n" +
        "\n" +
        "MATCH (f)-[:HOME_TEAM]-(ht:Team)-[:TEAM_COUNTRY]-(htc:Country)\n" +
        "MATCH (f)-[:HOME_TEAM]-(at:Team)-[:TEAM_COUNTRY]-(atc:Country)\n" +
        "\n" +
        "RETURN cmp, s, f, ht, at, htc, atc\n" +
        "ORDER BY f.matchDate DESC, ht.name DESC"
)
List<Fixture> getCompetitionYearFixtures(
         Long competitionId, Integer yearStart
);

我称这个方法如下:

List<Fixture> fixtures =
        fixtureRepository
                .getCompetitionYearFixtures(
                        competitionId, year);

尽管Fixture返回了所有预期的 s,但没有填充任何相关实体: 空置的灯具

但是,我发现如果我立即对返回的任何一个(并且只有一个)运行以下语句Fxture,那么每个Fixturein fixtures 都会突然被完全填充:

fixtureRepository.findOne(fixtures.get(0).getId(), 3);

如此: 填充夹具

所以我的问题是,有没有办法Fixture在第一次访问数据库后返回所有相关实体填充的 s,而不必返回?

我专门在 Cypher 中检索了我需要的所有内容,并且在其中使用depth3的想法findOne让我有点不舒服,因为将来我可能会添加新的关系,我不一定想让查询膨胀。


编辑 解决方案,感谢 František Hartman:

MATCH r1=(cmp:Competition)-[cmp_c:COMPETITION_COUNTRY]-(cmpc:Country)
WHERE ID(cmp)=16860
MATCH r2=(cmp)-[cmp_s:COMPETITION]-(s:Season)<-[s_f:SEASON]-(f:Fixture)
WHERE s.yearStart=2019
MATCH r3=(f)-[f_ht:HOME_TEAM]-(ht:Team)-[ht_c:TEAM_COUNTRY]-(htc:Country)
MATCH r4=(f)-[f_at:AWAY_TEAM]-(at:Team)-[at_c:TEAM_COUNTRY]-(atc:Country)
RETURN r1,r2,r3,r4
ORDER BY f.matchDate DESC,ht.name DESC

标签: graphneo4jspring-data-neo4j

解决方案


您需要返回您想要映射的所有内容,在您的情况下,您期望关系也被映射(即使您没有关系实体,关系也表示,例如夹具和主队是相关的)。

要查看 Neo4j 浏览器中确切返回的内容,请转到“浏览器设置”(左下角的 cog 图标)-> 取消选中“连接结果节点”

您查询关系(您可能会想出比 r1-r7 更好的名称):

MATCH (cmp:Competition)-[r1:COMPETITION_COUNTRY]-(cc:Country)
WHERE ID(cmp)=16860

MATCH (cmp)-[r2:COMPETITION]-(s:Season)<-[r3:SEASON]-(f:Fixture)
WHERE s.yearStart=2019

MATCH (f)-[r4:HOME_TEAM]-(ht:Team)-[r5:TEAM_COUNTRY]-(htc:Country)
MATCH (f)-[r6:HOME_TEAM]-(at:Team)-[r7:TEAM_COUNTRY]-(atc:Country)

RETURN cmp, s, f, ht, at, htc, atc, r1, r2, r3, r4, r5, r6, r7
ORDER BY f.matchDate DESC, ht.name DESC

findOne方法(深度参数为 3)加载所有内容,包括最多 3 个步骤的关系,这些内容将填充到数据的缓存实例中。


推荐阅读