Skip to content

Difficulty mapping InternalNodes to domain model objects in custom queries #2288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
alizadehei opened this issue Jun 15, 2021 · 2 comments
Closed
Labels
status: waiting-for-triage An issue we've not yet triaged

Comments

@alizadehei
Copy link

I have a class with the following structure:

@NoArgsConstructor
@Setter
@Getter
@Node
public class Person {
    @Id
    @GeneratedValue(GeneratedValue.UUIDGenerator.class)
    private UUID id;
    @Property
    private String name;
    @Property
    private String family;
    @Property
    private int age;

    public Person(String name, String family, int age) {
        this.name = name;
        this.family = family;
        this.age = age;
    }

}

I want to do a custom query like the following query:

MATCH (n:Person) return count(n) as count, n

I did this query using the neo4jClient and neo4jTemplate in different ways (mentioned below):

template.save(new Person("Reza" + new Random(System.currentTimeMillis()).nextInt(), "Mahdavi", 22));

// 1-
List<Person> result_1 = template.find(Person.class).matching("Match(n:Person) return count(n) as count,n").all();

// 2- 
Collection<Person> result_2 = client.query("Match(n:Person) return count(n) as count,n").fetchAs(Person.class).all();

// 3-
Collection<Map<String, Object>> result_3 = client.query("Match(n:Person) return count(n) as count,n").fetch().all();

Query 1 return a List of Persons without count record.
Query 2 throw an exception
Query 3 return a list of maps that map values are InternalNode not Person. in fact, the problem is that Person nodes are returned as InternalNodes, not Person. As a result, we need to manually map the InternalNodes to the domain model objects.
This is while in the Neo4j-ogm; The output of the session.query("") was a QueryResultModel whose result field was one list of maps that map values were Person.

How do I make a custom query that returns InternalNodes automatically mapped to the domain model objects؟

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 15, 2021
@meistermeier
Copy link
Collaborator

First of all, the mixture you are trying to return is cannot be mapped to the domain structure. The count is independent from the actual node.
What you can do is to use the Neo4jClient and do something like.

BiFunction<TypeSystem, MapAccessor, Person> mappingFunction = neo4jMappingContext.getRequiredMappingFunctionFor(Person.class);
Collection<QueryResultWrapper> wrapper = neo4jClient.query("Match(n:Person) return count(n) as count,n")
                .bindAll(map).fetchAs(QueryResultWrapper.class)
                .mappedBy((typeSystem, record) -> {
                    Person n = mappingFunction.apply(typeSystem, record.get("n"));
                    int count = record.get("count").asInt();
                    return new QueryResultWrapper(n, count);
                }).all();

Where the QueryResultWrapper is something that has the fields Person and a long/int for the count.

@alizadehei
Copy link
Author

Thank you for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants