0
votes

Suppose, we have the following data in neo4j DB ->

enter image description here

The java entity representation is as follows ->

 @NodeEntity
public class Place {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

@NodeEntity
public class Monument {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

@NodeEntity
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @Relationship(type = "VISITED", direction = Relationship.OUTGOING)
    private Monument monument;

    @Relationship(type = "STAYS", direction = Relationship.OUTGOING)
    private Place place;
}

Now, I want to fetch all persons also populating the linked place and monument, if present. This means, the cypher query will not only provide me List< Person> as result and the Monument and Place object should also be linked with each Person object, if the links are available (and otherwise null). To clarify it further, for Person 'Ron', I should be able to see the monument he visited and the place he stays, without performing any more queries to fetch the relationships. Similarly, for Person 'April', I should be able to see where she stays, but will not know which monument she visited because there is no link there.

With my basic knowledge in Cypher Query language, I have tried but could not get the desired result.

  1. If I provide both the relations in the query and fetch the corresponding pattern variable, I only get the Person 'Ron' in the result.

MATCH p=(place:Place)<-[STAYS]-(person:Person)-[VISITED]->(monument:Monument) RETURN p

  1. If I only provide the relation 'STAYS', I get 'Ron' and 'April'.

MATCH p=(person:Person)-[STAYS]->(place:Place) RETURN p

  1. If I query without the relationships, I only get the Person object and the monument and place are not linked [getMonument() and getPlace() is null even for Person 'Ron'].

MATCH p=(person:Person) RETURN p

I could not find a query where I get all of these.

1

1 Answers

2
votes

You need to put the relations into optional matches, like this:

MATCH (person:Person) 
OPTIONAL MATCH (person)-[:VISITED]->(monument) 
OPTIONAL MATCH (person)-[:STAYS]->(place)
return person, place, monument

Otherwise, neo4j treats the relations in your query 1) as required, that's why 'Ron' will be the only result.