Neo4j - получить все связанные узлы и отношения для данного узла - PullRequest
0 голосов
/ 20 апреля 2019

Я использую Neo4j (версия 3.4.1) и Spring-data-neo4j (5.0.10.RELEASE) в моем приложении. Я также использую OGM.

У меня есть следующие отношения между моими узлами:

enter image description here

Транспортное средство (V) имеет деталь (и) (P1 и P2). Запчасти можно купить у дилеров (D1, D2 и D3). Сами части могут быть связаны друг с другом (например, P2 связан с P1)

Я пытаюсь написать зашифрованный запрос, чтобы получить узел Part, соответствующий id. Я хочу получить узел вместе со связанными с ним узлами и связями.

Ниже мой запрос:

@Query(("MATCH (Vehicle:v{id:{vehicleId}}) \n" +
            "MATCH (Part:part{id:{id}}) \n" +
            "WITH DISTINCT part \n" +
            "MATCH q=(v)-[:HAS_PART]->(part)-[:FROM_DEALER|:IS_LINKED_WITH]->()\n" +
            "RETURN nodes(q), relationships(q)"))
    Optional<Part> findByIdForGivenPart(@Param("vehicleId") String vehicleId, @Param("id") String id);

Когда я запускаю запрос, передающий идентификатор части P1, я получаю правильный результат. Однако, когда я запускаю его, передавая id части P2, я получаю исключение:

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected at most 1   

что я понимаю, потому что в этом случае возвращаются две части.

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

Любая помощь будет принята с благодарностью.

Редактировать: добавлены запросы для создания образцов данных.

merge (v:Vehicle{id:'V1'})-[:HAS_PART]->(p:Part{id:'P1'})-[:FROM_DEALER]->(d1:Dealer{id:'D1'})

match(p:Part{id:'P1'})
merge (p)-[:FROM_DEALER]->(d2:Dealer{id:'D2'})

match (v :Vehicle{id:'V1'})
match (d2:Dealer{id:'D2'})
merge (v)-[:HAS_PART]->(p:Part{id:'P2'})-[:FROM_DEALER]->(d2)

match(p2:Part{id:'P2'})
match(p1:Part{id:'P1'})
merge (p2)-[:FROM_DEALER]->(d3:Dealer{id:'D3'})
merge (p2)-[:IS_LINKED_WITH]->(p1)

С уважением, V

1 Ответ

1 голос
/ 23 апреля 2019

Я вижу три проблемы здесь:

Во-первых, вы используете направленное отношение в третьем предложении MATCH от part до безымянного узла в конце:

MATCH q=(v)-[:HAS_PART]->(part)-[:FROM_DEALER|:IS_LINKED_WITH]->()

Это означает, что когда вы запрашиваете P1, не совпадает с P2, поэтому единственное: return P1

Вторая проблема заключается в том, что ваш запрос не совсем соответствует вашему методу, который объявлен как возвращающий Optional<Part>, в то время как ваш запрос хочет вернуть все узлы (и отношения) по этому же пути q. Также название метода (findByIdForGivenPart) не совсем отражает то, чего вы хотите достичь с его помощью.

Третья проблема заключается в том, что ваши первые два предложения MATCH, похоже, имеют псевдоним и указанные метки, переключенные в синтаксисе:

MATCH (Vehicle:v{id:{vehicleId}})
MATCH (Part:part{id:{id}})

Я считаю, что это должно быть:

MATCH (v:Vehicle {id:{vehicleId}})
MATCH (part:Part {id:{id}})

, что также наводит меня на мысль, что у вас могут быть некоторые тестовые данные на вашем графике с узлами, которые имеют метки, такие как v и part (вместо Vehicle и Part), возможно, с более ранних MERGE операторы, предназначенные для настройки тестовых данных.

...