Best way to fetch data from a birectional graph upto a certain depth?

I'm working on a project wherein we have to visualize graph data from Neo4J on a webpage. This data will be exported through our backend app (Java/Spring Boot) which will be connected to our Neo4J instance. Backend will send out a list of nodes and a list of relationships which will be then rendered on the UI.

In backend, I'm using spring-data-neo4j library and am following standard Entity mapping pattern. However, it's not quite fitting my requirements:

  • For a given root node, I have to query only till a given depth -- let's say n. But this library fetches all the records(connected nodes and relationships) for a root node.
  • There are serializing issues as nodes in my graph are bidirectionally connected. This is covered in this SO thread too.
  • Difficult to serialize the root entity and connected nodes into separate node only and relationship only lists.

Therefore, I decided to use custom queries for this and luckly found this section in spring docs - Database-side reduction. The result format returned by this query is exactly what I need:

MATCH p=(m:Movie{title: 'The Matrix'})<-[:ACTED_IN]-(:Person)-[:ACTED_IN*..0]->(:Movie)
WITH collect(p) as paths, m
WITH m,
reduce(a=[], node in reduce(b=[], c in [aa in paths | nodes(aa)] | b + c) | case when node in a then a else a + node end) as nodes,
reduce(d=[], relationship in reduce(e=[], f in [dd in paths | relationships(dd)] | e + f) | case when relationship in d then d else d + relationship end) as relationships
RETURN m, relationships, nodes;

This returns

[
{
 n: <target node>,
 relationships: [<relationships>...],
 nodes: [<nodes>...]
}]

However, I am not able to map it out to code which is aligned with spring data neo4j repository pattern. For testing purpose I tried using

interface CustomRepo extends Neo4jRepository<Person, Long> {
@Query("MATCH p=(m:Movie{title: 'The Matrix'})<-[:ACTED_IN]-(:Person)-[:ACTED_IN*..0]->(:Movie)
WITH collect(p) as paths, m
WITH m,
reduce(a=[], node in reduce(b=[], c in [aa in paths | nodes(aa)] | b + c) | case when node in a then a else a + node end) as nodes,
reduce(d=[], relationship in reduce(e=[], f in [dd in paths | relationships(dd)] | e + f) | case when relationship in d then d else d + relationship end) as relationships
RETURN m, relationships, nodes;")
List<Object> customQuery();
}

But it failed with this exception -

Records with more than one value cannot be converted without a mapper

https://community.neo4j.com/t/records-with-more-than-one-value-cannot-be-converted-without-a-mapper/54588. 

However, I don't really want to use Neo4J client and write the queries myself.

Is there anyway to achieve this with out of the box functionalities of Spring data neo4j library without writing custom queries and using neo4j client instance ?


Edit 1

Approach specific under "Neo4jClient/Working with result objects" section in the Spring Data docs - https://docs.spring.io/spring-data/neo4j/reference/appendix/neo4j-client.html#neo4j-client.result-objects handles my use case. The only problem is that I have to do lots of object conversion myself.

Is there anyway for the neo4j library to map it out for me ? Like convert it into proper objects without me needing to create objects explicitly ?

(Answer based on the Edit 1)
Have you also read the following section about using the mapping function from within the Neo4jClient? Neo4jClient :: Spring Data Neo4j
If the paragraph you linked already matches your needs, this should complete it :slight_smile:
You can autowire/inject the (Neo4j)MappingContext into the class you are using the Neo4jClient and retrieve the mapping function to be applied during the result processing as shown in the example.

Thanks, I looked into and it solves my problem to a certain extent. However, the list returned under "nodes" is heterogeneous in nature as there a bunch of different kind of nodes (labels).

I'll have to add a lot of conditional checks to use the appropriate bifunction for the conversion. Will probably have to use some clever design pattern. But thanks !