SDN4, Neo4j OGM @QueryResult Session.query and Pagable

389 views Asked by At

Right now due to an open GitHub issue https://github.com/neo4j/neo4j-ogm/issues/215 in Neo4j OGM I have to use a following workaround in order to convert org.neo4j.ogm.session.Session.query result that returns @QueryResult into List of this @QueryResult:

Example Cypher query:

 MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) WHERE id(parentD) = {decisionId}  OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) WHERE id(c) IN {criteriaIds} WITH childD, ru, u, vg.avgVotesWeight as weight  OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue375:Value)-[:SET_ON]->(sortCharacteristic375:Characteristic) WHERE id(sortCharacteristic375) = 375 RETURN childD AS decision, ru, u, toFloat(sum(weight)) as weight, sortValue375 ORDER BY weight DESC, sortValue375.value DESC, childD.createDate DESC SKIP 0 LIMIT 1000

Workaround:

@QueryResult
public class WeightedDecision {

    private Decision decision;

    private Double weight;

...
}

Result queryResult = session.query(characteristicCypher, parameters);

List<WeightedDecision> weightedDecisions = new ArrayList<>();

for (Map<String, Object> result : queryResult) {
    WeightedDecision weightedDecision = new WeightedDecision();
    weightedDecision.setDecision((Decision) result.get("decision"));
    weightedDecision.setWeight((double) result.get("weight"));
    weightedDecisions.add(weightedDecision);
}

Right now instead of List<WeightedDecision> I have to return Page<WeightedDecision>

How it can be done ? Please help me to change the code in order to translate queryResult into Page<WeightedDecision>

Also, how to provide a countQuery in this logic ?

1

There are 1 answers

3
K.E. On BEST ANSWER

Referring to this post Conversion of List to Page in Spring you can to the mapping from a resulting list to a Page instance with the org.springframework.data.domain.PageImpl implementation. In your case, after mapping the result to a List you can do following:

PageRequest pageable = new PageRequest(0, 2);
Page<WeightedDecision> page = new PageImpl<>(weightedDecisions, pageable, weightedDecisions.size());

Background: As far as I know in this moment it is not possible to use Pageable on custom queries in SDN (Paging and sorting in Spring Data Neo4j 4). Therefore you have to do the mapping on your own.

Your second question abount a count logic. In my opinion you have to call your query a second time with changes depending on what you want to count. For example to count the childD nodes:

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) WHERE id(parentD) = {decisionId}  
OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) WHERE id(c) IN {criteriaIds} WITH childD, ru, u, vg.avgVotesWeight as weight  
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue375:Value)-[:SET_ON]->(sortCharacteristic375:Characteristic) WHERE id(sortCharacteristic375) = 375 RETURN count(childD) AS result;