Criteria Builder in Neo4j

Posted By : Jasgeet Singh | 30-Nov-2017

In my one of the project, I got the requirment where I need to build criteria in Neo4j queries, so I used Session which serves as the main point of integration for the Neo4j OGM. It is very easy to use Session, let see:

 


Map queryParameters = new HashMap();
        String query = "MATCH (c:Client{citizenDead:false})-[r:GET_SERVICE_FROM]->(o:Organization) WHERE id(o)= {unitId} AND id(c) in {citizenIds} AND ( c.firstName=~{name} OR c.lastName=~{name} ) AND c.cprNumber STARTS WITH {cprNumber} with c,r\n";
        queryParameters.put("unitId", organizationId);
        queryParameters.put("name", clientFilterDTO.getName());
        queryParameters.put("cprNumber", clientFilterDTO.getCprNumber());
        queryParameters.put("phoneNumber", clientFilterDTO.getPhoneNumber());
        queryParameters.put("civilianStatus", clientFilterDTO.getClientStatus());
        queryParameters.put("skip", Integer.valueOf(skip));
        queryParameters.put("latLngs", clientFilterDTO.getLocalAreaTags());



      
        query +=   "OPTIONAL MATCH (c)-[:HAS_HOME_ADDRESS]->(ca:ContactAddress)  with ca,c,r\n";
        if(StringUtils.isBlank(clientFilterDTO.getPhoneNumber())){
            query += "OPTIONAL MATCH (c)-[:HAS_CONTACT_DETAIL]->(cd:ContactDetail) with cd,ca,c,r\n";
        }else{
            query += "MATCH (c)-[:HAS_CONTACT_DETAIL]->(cd:ContactDetail) WHERE cd.privatePhone STARTS WITH {phoneNumber} with cd,ca,c,r\n";
        }
        if(clientFilterDTO.getClientStatus() == null){
            query +=  "OPTIONAL MATCH (c)-[:CIVILIAN_STATUS]->(cs:CitizenStatus) with cs,cd,ca,c,r\n";
        }else{
            query +=  "MATCH (c)-[:CIVILIAN_STATUS]->(cs:CitizenStatus) WHERE id(cs) = {civilianStatus} with cs,cd,ca,c,r\n";
        }
        if(clientFilterDTO.getLocalAreaTags().isEmpty()){
            query +=   "OPTIONAL MATCH (c)-[:HAS_LOCAL_AREA_TAG]->(lat:LocalAreaTag) with lat,cs,cd,ca,c,r\n";
        }
        else{
            query +=   "MATCH (c)-[:HAS_LOCAL_AREA_TAG]->(lat:LocalAreaTag) WHERE id(lat) in {latLngs} with lat,cs,cd,ca,c,r\n";
        }
        query += "return {name:c.firstName+\" \" +c.lastName,id:id(c), age:c.age, emailId:c.email, gender:c.gender, cprNumber:c.cprNumber , citizenDead:c.citizenDead, joiningDate:r.joinDate,city:ca.city,";
        query += "address:ca.houseNumber+\" \" +ca.street1, phoneNumber:cd.privatePhone, workNumber:cd.workPhone, clientStatus:id(cs), lat:ca.latitude, lng:ca.longitude, ";
        query +=   "localAreaTag:CASE WHEN lat IS NOT NULL THEN {id:id(lat), name:lat.name} ELSE NULL END}  as Client ORDER BY c.firstName ASC SKIP {skip} LIMIT 20 ";
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(session.query(Map.class , query, queryParameters).iterator(), Spliterator.ORDERED), false).collect(Collectors. toList());

 

 


I am hoping here you knowabout

Optional keyword, so in this query you can see if User search by Phone number then that match should be mandatory otherwise I am keeping it optional as it could happen Citizens may not have phone number.We can add query parmaters by storing it in map, you can see above how we pass that and mapped attributes in query. I also showing here to convert the result getting from Session into the list of Map, you can also replace map with custom DTOs.

 

I hope this blog help you guys in building criteria query in your projects, happy coding !

About Author

Author Image
Jasgeet Singh

Jasgeet is a Sr. Lead developer .He is an experienced Groovy and Grails and has worked on designing & developing B2B and B2C portals using Grails technologies.

Request for Proposal

Name is required

Comment is required

Sending message..