Search code examples
neo4jcypherneo4j-apoc

Cypher query to return graph as object, where each parent node contains an array of its children?


I have a graph like the one below:

enter image description here

What cypher query must I use to return the graph as an object, where each parent node contains an array of its children nodes?

Example:

state: {
  name: 'New York'
  publishingCompanies: [
    {
      name: 'Penguin'
      authors: [
        {
          name: 'George Orwell',
          books: [
            { name: 'Why I Write'},
            { name: 'Animal Farm'},
            { name: '1984' }
          ]
        },
        {
          name: 'Vladimir Nobokov'
          books: [
            { name: 'Lolita' }
          ]
        },
        ...
      ]
    },
    { 
      name: 'Random House',
      authors: [
        ...
      ]
    }
  ]
}

I tried to use apoc.convert.toTree, but it returned an array of paths from State to Book.


Solution

  • This should return the state object (assuming the state name is passed in via the stateName parameter):

    MATCH (s:State)
    WHERE s.name = $stateName
    OPTIONAL MATCH (s)-[:IS_STATE_OF]->(c)
    OPTIONAL MATCH (c)-[:PUBLISHED_FOR]->(a)
    OPTIONAL MATCH (a)-[:WROTE]->(b)
    WITH s, c, a, CASE WHEN b IS NULL THEN [] ELSE COLLECT({name: b.name}) END AS books
    WITH s, c, CASE WHEN a IS NULL THEN [] ELSE COLLECT({name: a.name, books: books}) END AS authors
    WITH s, CASE WHEN c IS NULL THEN [] ELSE COLLECT({name: c.name, authors: authors}) END AS pcs
    RETURN {name: s.name, publishingCompanies: pcs} AS state