Search code examples
jsonneo4jcypherneo4j-apochierarchical-trees

NEO4j Return a nested, hierarchical JSON from a DB


ALLRELATED

I have a Tree Model on db like it's shown on the picture

  • City node is linked to Region node by IS_A_City_BELONGING_TO
  • Sector node is linked to Region node by IS_A_SECTOR_BELONGING_TO_THAT_REGION
  • Sector node is linked to City node by IS_A_SECTOR_BELONGING_TO_THAT_CITY

The hierarchical nested json ideal output is as follows

<code>needed json file hierarchical tree</code>

enter image description here

Indexes
   ON :TTL(ttl) ONLINE 
   ON :City(cityName) ONLINE  (for uniqueness constraint)
   ON :Region(region) ONLINE  (for uniqueness constraint)
   ON :Sector(sectorName) ONLINE  (for uniqueness constraint)

Constraints
   ON ( city:City ) ASSERT city.cityName IS UNIQUE
   ON ( region:Region ) ASSERT region.region IS UNIQUE
   ON ( sector:Sector ) ASSERT sector.sectorName IS UNIQUE

How to generate the json file from db using cypher request.

THANK YOU very much.


Solution

  • So... Your Hierarchy is kinda hard to read... so I'll focus on the JSON response part. While Neo4j doesn't have Map as a property type, it is valid inside Cypher.

    To aggregate results into a map, you can use this format

    MATCH (c:City)<--(s:Sector)
    RETURN {city_node:c, city_properties:PROPERTIES(c) name:c.name, sectors:COLLECT(s)} as city
    

    Basically {} as varname defines your map, and the contents of {} define the key-value pairs.

    And you can merge 2 maps with the + operator like WITH map1 + map2 as mymap. In the case of conflict, the value in the second map takes priority.

    If you only want the properties of a node, and not the whole node, you can use the PROPERTIES(c) function instead of passing in the node.

    One thing you will quickly notice, is this will not work recursively. It looks like in your case, it's fixed at 2 nest levels deep. So that limitation shouldn't be a problem.

    On a side note, if this is meant to scale, you may want to make your Cypher paged (LIMIT+SKIP) to improve response times. (Only return what you need as you need it) On that note, it may be better to aggregate this client side, as you will probably be returning some sectors frequently for each city.