0
votes

I have 3 types of node in my graphDb. Skill, SkillSubCluster & SkillCluster. A Skill node is connected to one or many SkillSubCluster node(1 to many relationship) and a SkillSubCluster node is connected to a single SkillCluster node (1 to 1 relationship).

I want to find all the skills given a skillCluster name. I have come up with this cypher query -

match(n:SkillCluster {CleanedText: "arts"}) match(n)<-[parent]-(x)<-[belongsTo]-(y) return y

The number of nodes can be large so I am thinking of returning a paginated result. This can be easily done using skip and limit operators. Also I would like to return total number of skills for a given skillCluster node.

Corresponding cypher query would be

match(n:SkillCluster {CleanedText: "arts"}) match(n)<-[parent]-(x)<-[belongsTo]-(y) return count(y)

I am trying to do the same using neo4j-ogm for java.

My Skill Class is

public class Skill {
    @Id @GeneratedValue
    private Long id;
    private String Name;
    private String CleanedText;

    @Relationship(type = "BelongsTo", direction = Relationship.OUTGOING)
    private Set<SkillSubCluster> belongsTo = new HashSet<>();
}

Its corresponding DAO class

public class SkillDAO extends GenericDAO<Skill>{
    public SkillDAO(Session session) {
        super(session);
    }

    protected Class<Skill> getEntityType() {
        return Skill.class;
    }   
}

and my Generic DAO class -

public abstract class GenericDAO<T> {
    private static final int DEPTH_LIST = 0;
    private static final int DEPTH_ENTITY = 1;  
    private Session session;

    public long filterCount(Iterable<Filter> filters){
        return session.count(getEntityType(), filters);
    }

    public T find(Long id) {
        return session.load(getEntityType(), id, DEPTH_ENTITY);
    }

    public T find(String name) {
        return session.load(getEntityType(), name, DEPTH_ENTITY);
    }

    public void delete(Long id) {
        session.delete(session.load(getEntityType(), id));
    }

    public void createOrUpdate(T entity) {
        session.save(entity, DEPTH_ENTITY);
        //return find(entity.id);
    }

    protected abstract Class<T> getEntityType();

    public GenericDAO(Session session) {
        this.session = session;
    }
}      

Is it possible to return objects other than Skill Class or get results of complex cypher queries like group by etc.

1

1 Answers

1
votes

After digging for a while I came up with the right way to do it. So in my GenericDAO abstract class I had to add the following method -

public abstract class GenericDAO<T> {
    // Rest of the implementation from above 

    public Result runComplexQuery(String query){
        return session.query(query, Collections.emptyMap());    
    }

    // ..................
}

and then the following code to get the count-

public long getNodeCount(String clusterName){
    query = "match(n:SkillCluster {CleanedText: \"" + clusterName.toLowerCase() + "\"}) " 
    + "match(n)<-[parent]-(x)<-[belongsTo]-(y) return count(y) as numSkillNodes";

    Iterable<Map<String, Object>> results = skillSubClusterDAO.runComplexQuery(query);

    for(Map<String, Object> row: results){
        count = (long) row.get("numSkillNodes");
        System.out.println(count);
    }
}