Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-31-2021 07:07 AM
I want to query nodes that have a relation to eachother and return them, including the relation.
Example from the Movies dataset:
@Query("MATCH (actor:Person)-[actedIn:ACTED_IN]->(movie:Movie) WHERE ID(movie) = $movie.__id__ RETURN actor, actedIn, movie")
List<PersonActedInMovieDTO> queryMovie(Movie movie);
If I use a DTO for this
public class ActorActedInMovieDTO {
private Actor actor;
private ActedIn actedIn;
private Movie Movie;
}
I get this exception:
org.neo4j.driver.exceptions.value.NotMultiValued: RELATIONSHIP is not iterable
If I leave out the relationship the code works just fine, but then the actor object returned, does not even have its relationship attributes filled, i. e. the List attribute actedIn is empty.
Is DTO even the right way to do this? I find it very hard to understand what kind of query/mapping/projection to use for different use-cases. Generally, I want to get instances that I can work with, and write back to the database. Is it better to revert back to neo4j-OGM for this?
Solved! Go to Solution.
11-02-2021 08:31 AM
You would have an entity definition as shown here (with all the other ones involved like Actor
, Person
..) spring-data-neo4j/Movie.java at 495bd21eb530405b145bb33573b10e36f2109656 · spring-projects/spring-da...
Just a shortened version:
@Node
public final class Movie {
// id and other properties
@Relationship(value = "ACTED_IN", direction = Direction.INCOMING)
private List<Actor> actors;
// other things
}
With your query
MATCH (actor:Person)-[actedIn:ACTED_IN]->(movie:Movie) WHERE ID(movie) = $movie.__id__ RETURN actor, actedIn, movie
you would have to change the returned values in something like the pattern root node, list(relationships), list(related nodes). This is also described in the documentation chapter Custom queries
MATCH (actor:Person)-[actedIn:ACTED_IN]->(movie:Movie) WHERE ID(movie) = $movie.__id__ RETURN collect(actor), collect(actedIn), movie
I did this now movie-centric because it aligns better to the example entity linked above.
10-31-2021 10:49 AM
Hello
What this means is that you need to connect to next iterable node from previous node and the connection is missing between 2 Nodes. It can be either thought as doubly linked list with one pointer dangling somewhere else rather than pointing to the right node. So you have not correctly embeded left referencing on right hand side and that is causing troubles in many areas. Best solution is take the dangling node and embed it in chain on Nodes that connect to the rightly referenced node. Once that is done your error will go. So you need to do apt error handling mechanism in your code to arrive at the right solution.
Thanking you
G Sameer S
11-01-2021 08:08 AM
Hi @sameer.gijare14,
if that's what the exception means, then there is another bug in SDN, because if I do that query on neo4j, I get exactly what I expect: Actors connected to the movie. No dangling relation ends. See the query result:
╒═════════════════════════════════════════╤═════════════════════════╤══════════════════════════════════════════════════════════════════════╕
│"actor" │"actedIn" │"movie" │
╞═════════════════════════════════════════╪═════════════════════════╪══════════════════════════════════════════════════════════════════════╡
│{"name":"Emil Eifrem","born":1978} │{"roles":["Emil"]} │{"tagline":"Welcome to the Real World","title":"The Matrix","released"│
│ │ │:1999} │
├─────────────────────────────────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"Hugo Weaving","born":1960} │{"roles":["Agent Smith"]}│{"tagline":"Welcome to the Real World","title":"The Matrix","released"│
│ │ │:1999} │
├─────────────────────────────────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"Laurence Fishburne","born":1961}│{"roles":["Morpheus"]} │{"tagline":"Welcome to the Real World","title":"The Matrix","released"│
│ │ │:1999} │
├─────────────────────────────────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"Carrie-Anne Moss","born":1967} │{"roles":["Trinity"]} │{"tagline":"Welcome to the Real World","title":"The Matrix","released"│
│ │ │:1999} │
├─────────────────────────────────────────┼─────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"Keanu Reeves","born":1964} │{"roles":["Neo"]} │{"tagline":"Welcome to the Real World","title":"The Matrix","released"│
│ │ │:1999} │
└─────────────────────────────────────────┴─────────────────────────┴──────────────────────────────────────────────────────────────────────┘
It could be that the nodes at the end of the relation are not correctly filled. As I worte, there are no relations in the node objects I get back, when I only RETURN movie, actor
.
11-02-2021 01:05 AM
No, this is not a bug in SDN but an intended limitation of the projection mechanism.
The DTO projection has to reflect, for example, a Movie
but cannot be used as a "collector class" of arbitrary return values.
A projection is always linked to one domain entity.
11-02-2021 02:30 AM
Thanks @gerrit.meier. But what would be the right way to map that kind of query to objecs? As I said, I feel kind of lost to find the right type of mapping queries to objects.
11-02-2021 08:31 AM
You would have an entity definition as shown here (with all the other ones involved like Actor
, Person
..) spring-data-neo4j/Movie.java at 495bd21eb530405b145bb33573b10e36f2109656 · spring-projects/spring-da...
Just a shortened version:
@Node
public final class Movie {
// id and other properties
@Relationship(value = "ACTED_IN", direction = Direction.INCOMING)
private List<Actor> actors;
// other things
}
With your query
MATCH (actor:Person)-[actedIn:ACTED_IN]->(movie:Movie) WHERE ID(movie) = $movie.__id__ RETURN actor, actedIn, movie
you would have to change the returned values in something like the pattern root node, list(relationships), list(related nodes). This is also described in the documentation chapter Custom queries
MATCH (actor:Person)-[actedIn:ACTED_IN]->(movie:Movie) WHERE ID(movie) = $movie.__id__ RETURN collect(actor), collect(actedIn), movie
I did this now movie-centric because it aligns better to the example entity linked above.
11-02-2021 09:09 AM
Thanks @gerrit.meier - I read that part of the documentation, but did not get it. Now it's clear how that works.
All the sessions of the conference are now available online