Modeling a tree and getting a subtree from a node

I am exploring dgraph and have noob question:
I am representing a tree using dgraph. How do I get a subtree ie. recursively get all children of a uid?

I populated the following json data using the mutate api:

{
  "set": [
    {
      "jungle": {
        "animals": {
          "lion": {
            "name": "Simba"
          },
          "elephant": {
            "name": "Ele"
          }
        },
        "birds":{
          "parrot": {
            "name": "Zuzu"
          },
          "chicken": {
            "name": "Chica"
          }
        }
      }
    }
  ]
}

after which I queried:

{
  parent as p(func: has(animals)){
  }

  me(func: uid(parent)) @recurse(depth: 10, loop: true){
    uid
    expand(_all_)
  }
}

I get:

{
  "p": [],
  "me": [
    {
      "uid": "0x3c",
      "animals": [
        {
          "uid": "0x3d"
        }
      ],
      "birds": [
        {
          "uid": "0x40"
        }
      ]
    }
  ]
}

It looks like I am doing it wrong. Why it doesn’t return leaf nodes (parrot, chicken etc) with their names?

Thanks

Looks like you found a bug. @recurse should work with your data set. Can you please file a GitHub issue about it? https://github.com/dgraph-io/dgraph/issues/new/choose.

Actually, I’ll create an issue. Stand by. :slight_smile:

Awesome! Please share the issue link here so I can follow :slight_smile:

1 Like

Issue created here: @recurse query not fetching entire subgraph from root node · Issue #2555 · dgraph-io/dgraph · GitHub

Hey guys, I don’t thing we have a bug here. The recurse directive usage that is wrong.

For this case the usage would be:

{
   me(func: has(jungle)) @recurse(depth: 10, loop: true) {
    uid
    name
    jungle 
    animals
    birds
    lion
    elephant
    parrot
    chicken
  }
}

Response

{
  "data": {
    "me": [
      {
        "uid": "0x5",
        "jungle": [
          {
            "uid": "0x6",
            "animals": [
              {
                "uid": "0x7",
                "lion": [
                  {
                    "uid": "0x8",
                    "name": "Simba"
                  }
                ],
                "elephant": [
                  {
                    "uid": "0x1",
                    "name": "Ele"
                  }
                ]
              }
            ],
            "birds": [
              {
                "uid": "0x2",
                "parrot": [
                  {
                    "uid": "0x3",
                    "name": "Zuzu"
                  }
                ],
                "chicken": [
                  {
                    "uid": "0x4",
                    "name": "Chica"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

Update

Just for fun you can create one (or more) Node (s) as templates to use in recurse directive. And then expand the predicates like this:

{
  "set": [
    {
      	"model": "root", 
        "animals": {
          "uid": "0x1" #0x1 is dummy node for us
        },
        "name": " ",
        "lion": {
          "uid": "0x1"
        },
        "elephant": {
          "uid": "0x1"
        },
        "birds": {
          "uid": "0x1"
        },
        "parrot": {
          "uid": "0x1"
        },
        "chicken": {
          "uid": "0x1"
        }
    }
  ]
}

Query

{
  var(func: has(model)) {
     pred as _predicate_
  }
  parent as var(func: has(animals)) @filter(NOT has(model) ) 

  me(func: uid(parent)) @recurse(depth: 10, loop: true) {
    expand(val(pred)) {
      expand(_all_)
    }
  }
}

Response

{
  "data": {
    "me": [
      {
        "animals": [
          {
            "lion": [
              {
                "name": "Simba"
              }
            ],
            "elephant": [
              {
                "name": "Ele"
              }
            ]
          }
        ],
        "birds": [
          {
            "parrot": [
              {
                "name": "Zuzu"
              }
            ],
            "chicken": [
              {
                "name": "Chica"
              }
            ]
          }
        ]
      }
    ]
  }
1 Like