cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Neo4j - Get all the related nodes and relationships for a given node

Hi, I am trying to write a cypher query to get all the related nodes and relationships of a matched node.
Here is my node relationship

A vehicle (V) has Part(s) (P1 and P2). Parts can be bought from dealers (D1, D2 and D3). Part themselves can be linked to each other (for e.g P2 is linked with P1)
I am trying to write a cypher query to get a Part node matching an id. I want to get the node along with its related nodes and relationships.

Below is my query:

@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);

When I run the query passing id of Part P1, I get the correct result. However, when I run it passing id of Part P2, I get an exce ```ption :

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expect``ed at most 1

which I understand is because in this case two parts are getting returned.

I would like to know the cypher query syntax so that I get correct result (i.e P2) along with its related nodes when I pass id of P2. I want that the P1 node should also be returned as P2 is linked with P1.


Any help would be highly appreciated.

Regards,
Varun

6 REPLIES 6

ameyasoft
Graph Maven

Node label and alias name are interchanged.:

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

Change your query to reflect this query:
MATCH (v:Vehicle {id:"V1"})-[:HAS_PART]->(p:Part)-[:FROM_DEALER]-(d:Dealer)
RETURN v, p, d;

Result:

2X_0_0aab961ecbce98b750c37da9a1eb3bc75bec9015.png
MATCH (v:Vehicle {id:"V1"})-[:HAS_PART]->(p:Part {id:"P1")-[:FROM_DEALER]-(d:Dealer)
RETURN v, p, d;

Result:
2X_7_7f97c58371885a6bf75906af4e0ef828ebcdc0ca.png

You will get same graph except with P2 in place of P1.

ameyasoft
Graph Maven

Q: I want that the P1 node should also be returned as P2 is linked with P1

A. Here is the Cypher query with no direction:

MATCH (v:Vehicle)--(p:Part)--(d)
WHERE....
RETURN v, p, d;

Result :
p.id = "P1"

2X_7_79518e51a75f9885e244e3d3b30b136c295fb436.png

p.id = "P2"

2X_e_ead90e9418f4d57fd4c7a60f972f7cee8375a16c.png

Thanks for your reply. However, my requirement is that when I the pass Part.id="P1" only part P1 should be returned (Part P2 should not be returned as there is no "IS_LINKED_WITH" relationship from P1 to P2 (direction is important)) .
When I pass Part.id="P2", Part P2 should be returned with Part P1 set in it, as there is "IS_LINKED_WITH" relationship from P2 to P1 (direction is important).
Also, a vehicle can have many parts ( not just P1, P2). I have just simplified the diagram for brevity hence we will have to use Part.id to select specific parts.
I am not sure what should be the return type of the method findByIdForGivenPart so that it only returns the selected Part along with its related nodes.
Hope I have made the requirement clear.
Thanks again for your help and appreciate your time.

Regards,
Varun

But then in the one case where the IS_LINKED_WITH relationship is used you still get both?
Do you want instead the other part returned?

Then you might want to use (p)-[:IS_LINKED_WITH*0..1]->(part)
and use part in the rest of your query.

MATCH (:Part{id:{id}})-[:IS_LINKED_WITH*0..1]->(part)

Also you shouldn't need the "WITH distinct part"

Thanks for your reply Michael.
Yes, I want that when I pass part.id="P1" it should only return P1 whereas when I pass part.id="P2" it should return both P1 and P2. (but I want that P1 should be set within P2) . It shouldn't be returned as separate node in the result (hope you get what I mean)
I have now changed the query to the following:

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

So now it returns both Parts P1 and P2 when part.id="P2"( P1 is returned as separate Part and is also set within P2). I now filter out P1 on the java side and only retaining P2 (with P1 set within it)
I want that it should not return P1 as separate node at all (and avoid the overhead of filtering it out).

regards,
Varun

Hi there. Same problem here, i'll try to explain my context.

I have some Patterns, some Creations concerning a Pattern. Creation can have some Images. A Pattern can be represented by an Image.

Structure is like :

Pattern {
  ...
  Image imgRepresent;
}

Creation {
  ...
  Pattern pattern;
  Collection<Image> images;
}

Image {
  Creation creation
}

I need to fetch an Image by its id, and also fetch the Creation related to it, the Pattern related to this Creation, and the imgRepresent (the Image that represent this Pattern).

My query :

MATCH (v:Image {id: {id}})-[b:BELONG_CREATION]-(p:Creation)-[c:CREA_CONCERNS_PATTERN]-(pa:Pattern) "
			+ "OPTIONAL MATCH (pa)-[e:IMAGE_REPRESENTS]-(i:Image) "
			+ "return v, b, p, c, pa, i"
Optional<Image> findCustById(String id);

Then on java side i'm supposed to be able to do :

Image img = repo.findCustById(123).get();
img .getCreation().getPattern().getImgRepresent()

Unfortunately repo.findCustById(123) throws the error " Incorrect result size: expected at most 1".
I've changed the return type to
List< Image > findCustById(String id);
to see what's returned, and indeed I have 2 Image objects, the one with the id 123, but also the one which is in Pattern.imgRepresent.

Is there a solution here to only get the Image corresponding to the filter id=123, and the nested Image only in Pattern, and not in resultset?

Thx