0

I have a graph database like this one enter image description here

Is there a way to return the two subtrees as a tree structure excluding "B" relationships? My wish is to generate a JSON describing the hierarchical structure of the two subtrees in a format like this

{
  "graph":{
    "food": {
      "attr1":"some attr",
      "children": {
        "pizza":{
          "attr1":"some attr",
          "children":{
            "pizza1":{
              "attr1":"some attr"
            },
            "pizza2":{
              "attr1":"some attr"
            },
            "pizza3":{
              "attr1":"some attr"
            }
          }
        },
        "pie":{
          "attr1":"some attr",
          "children":{}}
      }
    },
    "topping": {
      "attr1":"some attr",
      "children": {
        "meat":{
          "attr1":"some attr",
          "children":{
            "pepperoni":{
              "attr1":"some attr"
            },
            "beef":{
              "attr1":"some attr"
            }
          }
        },
        "vegetables":{
          "attr1":"some attr",
          "children":{
            "onion":{
              "attr1":"some attr"
            },
            "eggplant":{
              "attr1":"some attr"
            }
          }
        }
      }
    }
  }
}

I know there's APOC plugin for Neo4j but I don't know if it can be used for something like this.

Gianluca
  • 165
  • 3
  • 10

1 Answers1

0

The APOC procedure apoc.convert.toTree can produce each subtree (but using a generic JSON schema). For example:

MATCH p=(f:Foo)-[:A*0..]->(:Foo)
WHERE f.id IN ['FOOD', 'TOPPING']
WITH COLLECT(p) AS ps
CALL apoc.convert.toTree(ps, false) YIELD value
RETURN value AS subtree

[UPDATE 1]

If FOOD and TOPPING are not property values but labels, you can do this:

MATCH p=(f)-[:A*0..]->()
WHERE f:FOOD OR f:TOPPING
WITH COLLECT(p) AS ps
CALL apoc.convert.toTree(ps, false) YIELD value
RETURN value AS subtree

[UPDATE 2]

If you also want to ignore the leaf node on each path (that has at least 1 relationship), you can use the APOC function apoc.path.slice to eliminate the last relationship in a path:

MATCH p=(f)-[:A*0..]->()
WHERE f:FOOD OR f:TOPPING
WITH COLLECT(CASE WHEN LENGTH(p) > 0 THEN apoc.path.slice(p, 0, LENGTH(p)-1) ELSE p END) AS ps
CALL apoc.convert.toTree(ps, false) YIELD value
RETURN value AS subtree
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • in my case "FOOD" and "TOPPING" are labels. Is there a way to filter the label as if it was a property? – Gianluca Jul 23 '20 at 09:21
  • thank you. Is there a way instead of not returning the leaves? I mean return in the same json structure just FOOD,PIZZA,TOPPING, MEAT and Vegetables? – Gianluca Jul 24 '20 at 07:46
  • See my updated answer. In the future, you should create a new question. – cybersam Jul 24 '20 at 18:32
  • Thank you. How can I export directly to a json file using convert.toTree? – Gianluca Jul 29 '20 at 08:13
  • See the APOC procedures for [exporting to JSON files](https://neo4j.com/docs/labs/apoc/current/export/json/). – cybersam Jul 29 '20 at 19:45