2
votes

I'm trying to write a query that returns a fairly large amount of data (200ish nodes). The nodes are very simple:

public class MyPojo{
    private String type;
    private String value;
    private Long createdDate;

    ...
} 

I originally used the Spring Data Neo4j template interface, but found that it was very slow after around 100 nodes were returned.

public interface MyPojoRepository extends GraphRepository<MyPojo> {
    public List<MyPojo> findByType(String type);
}

I turned on debugging to see why it was so slow, and it turned out SDN was making a query for each node's labels. This made sense, as I understand SDN it needs the labels to do its duck-typing. However, Cypher returns all pertinent data in one go so there's no need for this.

So, I tried rewriting it as a Cypher query instead:

public interface MyPojoRepository extends GraphRepository<MyPojo> {
    @Query("MATCH(n:MyPojo) WHERE n.type = {0} RETURN n")
    public List<MyPojo> findByType(String type);
}

This had the same problem. I dug a little deeper, and while this query returned all node data in one go, it leaves out the labels. There is a way to get them, which works in the Neo4j console so I tried it with SDN:

"MATCH(n:MyPojo) WHERE n.type = {0} RETURN n, labels(n)"

Unfortunately, this caused an exception about having multiple columns. After looking through the source code, this makes sense because Neo4j returns a map of returned columns which in my case looked like: n, labels(n). SDN would have no way of knowing that there was a label column to read.

So, my question is this: is there a way to provide labels as part of the Cypher query to prevent needing to query again for each node? Or, barring that, is there a way to feed SDN a Node containing labels and properties and convert it to a POJO?

Note: I realize that the SDN team is working on using Cypher completely under the hood in a future release. As of now, a lot of the codebase uses the old (and, I believe, deprecated) REST services. If there is any future work going on that would affect this, I would be overjoyed to hear about it.

1

1 Answers

3
votes

You're right it would be solvable for the simple use-case and should also solved.

Unfortunately the current APIs don't return the labels as part of the node so we would have to rewrite the inner workings to generate the extra meta-information and return all of that correctly.

One idea is to use RETURN {id:id(n), labels:labels(n), data:n)} as n for the full representation. The problem is this breaks with user defined queries.

Not sure when and how we can schedule that work. Feel free to raise it as JIRA issue or watch/upvote any related issues.