Spring Neo4j @Query не заполняет связанные объекты до тех пор, пока не будет вызван последующий .findOne - PullRequest
0 голосов
/ 13 октября 2019

У меня есть следующий 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 с возвращены, ни один из связанных объектов не заполнен: Unpopulated Fixtures

Тем не менее, я обнаружил, что если я немедленно выполню следующую инструкцию для любого (и только одного) из возвращенных Fxture с, то каждый Fixture в fixture с внезапно полностью заполняется:

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

Таким образом: Populated Fixtures

Итак, мой вопрос, есть ли способ вернуть Fixture со всеми связанными объектами, заполненными после первой поездки? в базу данных, без необходимости возвращаться?

Я специально извлек все, что мне было нужно в Cypher, и идея использования depth из 3 в findOne - это то, что мне немного не по себе, так как в будущем я могу добавить новые отношения, которыеЯ не буду обязательно хотеть раздутый запрос.


РЕДАКТИРОВАТЬ Решение, благодаря Франтишеку Хартману:

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

1 Ответ

1 голос
/ 14 октября 2019

Вам необходимо вернуть все, что вы хотите отобразить, в вашем случае вы ожидаете, что отношения также будут отображены (даже если у вас нет сущностей отношений, отношения говорят, например, что прибор и домашняя команда связаны).

Чтобы увидеть, что именно возвращается в вашем браузере 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 шагов, которые будут заполнены вкэшированные экземпляры ваших данных.

...