Neo4j Extending by JAVA with aggregate functions

7 views
Skip to first unread message

Hayden Nguyen

unread,
Jul 11, 2018, 5:35:19 PM7/11/18
to Neo4j

Hi all, this is my cypher query at the moment


MATCH (sch:School)<-[:IN_SCHOOL]-(cla:Class1)<-[:IN_CLASS]-(stu:Student)
WHERE sch.schoolId=1
RETURN count(stu) as numberOfStudent
, AVG(stu.mathScore) AS avgScore
, MIN(stu.mathScore) AS minScore
, MAX(stu.mathScore) AS maxScore
, percentileDisc(stu.mathScore,0.1) AS per10thScore
, percentileDisc(stu.mathScore,0.1) AS medianScore
, percentileDisc(stu.mathScore,0.1) AS per90thScore

So as you can see this cypher will return the summary of all students, which will show the average score for Math subject as well as min, max and percentile

And in some case the query become very complex which I want to fully control over it, so I create me procedure by extending Neo4j here is my function written in Java

private static final RelationshipType IN_SCHOOL= RelationshipType.withName("IN_SCHOOL");
private static final RelationshipType IN_CLASS= RelationshipType.withName("IN_CLASS");
private static final Label School = Label.label("School");
private static final Label Class1 = Label.label("Class1");
private static final Label Student = Label.label("Student");

@Context
public GraphDatabaseService neo4j;

@UserFunction
@Description("Summary by School ID")
public List<Map<String, Object>> getSchoolSummary() {
    Transaction tx = neo4j.beginTx();
    List<Map<String, Object>> result = new ArrayList<>();
    try {
        Map<String, Object> conditions = new HashMap<String, Object>();
        conditions.put("schoolId", "1");
        ResourceIterator<Node> schools = neo4j.findNodes(School, conditions);

        while (schools.hasNext()) {
            Iterable<Relationship> inScholls = schools .next().getRelationships(IN_SCHOOL, Direction.INCOMING);
            while (inScholls.iterator().hasNext()) {
                Node class1 = inScholls.iterator().next().getEndNode();
                Iterable<Relationship> inClasses = class1.getRelationships(IN_CLASS, Direction.INCOMING);
                while (inClasses.iterator().hasNext()) {
                    Node student = inClasses.iterator().next().getEndNode();
                    //TODO AVG, MIN, MAX, PERCENTILE PLEASE HELP
                }
            }
        }

        tx.success();
    } finally {
        tx.close();
    }
}

So my question is how could I use count, sum, avg and all other neo4j aggregate functions inside my extended class


Thanks all

Michael Hunger

unread,
Jul 11, 2018, 5:44:55 PM7/11/18
to ne...@googlegroups.com
I don't think your java code will get simpler than the Cypher statement.

I added custom aggregation functions in APOC and used HdrHistogram there. You can also use Java 8 stream statistics.


Michael

--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages