Spring Neo4j @Query 在调用后续的 .findOne 之前不会填充相关实体
Spring Neo4j @Query not populating related entities until a subsequent .findOne called
我有以下 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
,但填充了 none 的相关实体:
但是,我发现如果我立即对返回的 Fxture
中的任何一个(并且只有一个)执行以下语句 运行,那么 [=20 中的每个 Fixture
=]s 突然填满:
fixtureRepository.findOne(fixtures.get(0).getId(), 3);
这样:
所以我的问题是,有没有一种方法可以在第一次访问数据库后返回包含所有相关实体的 Fixture
,而无需返回?
我专门在 Cypher 中检索了我需要的所有内容,在 findOne
中使用 3 的 depth
的想法让我有点不舒服,因为将来我可能会添加我不一定要使查询膨胀的新关系。
编辑
解决方案,感谢 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
您需要 return 您想要映射的所有内容,在您的情况下,您希望关系也被映射(即使您没有关系实体,关系表示例如夹具和主队有关系)。
要查看 Neo4j 浏览器中 return 的确切内容,请转到 "Browser settings"(齿轮图标左下角)-> 取消选中 "Connect result nodes"
您查询关系(您可能会想出比 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 个步骤的关系,它们将填充到数据的缓存实例中。
我有以下 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
,但填充了 none 的相关实体:
但是,我发现如果我立即对返回的 Fxture
中的任何一个(并且只有一个)执行以下语句 运行,那么 [=20 中的每个 Fixture
=]s 突然填满:
fixtureRepository.findOne(fixtures.get(0).getId(), 3);
这样:
所以我的问题是,有没有一种方法可以在第一次访问数据库后返回包含所有相关实体的 Fixture
,而无需返回?
我专门在 Cypher 中检索了我需要的所有内容,在 findOne
中使用 3 的 depth
的想法让我有点不舒服,因为将来我可能会添加我不一定要使查询膨胀的新关系。
编辑 解决方案,感谢 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
您需要 return 您想要映射的所有内容,在您的情况下,您希望关系也被映射(即使您没有关系实体,关系表示例如夹具和主队有关系)。
要查看 Neo4j 浏览器中 return 的确切内容,请转到 "Browser settings"(齿轮图标左下角)-> 取消选中 "Connect result nodes"
您查询关系(您可能会想出比 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 个步骤的关系,它们将填充到数据的缓存实例中。