Traverse Deeply Nested Graph Easily

Sample Data:

{'uid': '0xa0', '_Person': '*', 'title': 'Alpha'}
{'uid': '0xa1', '_Person': '*', 'title': 'Bravo'}
{'uid': '0xa2', '_Person': '*', 'title': 'Charlie'}
{'uid': '0xa3', '_Person': '*', 'title': 'Delta'}

Sample Relationships:

Alpha -> Bravo
Bravo -> Charlie
Charlie -> Delta

Query:

{
   all (func: has(_Person)) 
        @filter(eq(title, Alpha)) {
            uid
            expand(_all_) {
                uid
                expand(_all_) {
                    uid
                    expand(_all_) {
                        uid
                        expand(_all_) {
                            
                        }   
                    }
                }
            }
        }
    }

Result

"all": [
      {
        "uid": "0xa0",
        "friend": [
          {
            "uid": "0xa1",
            "friend": [
              {
                "uid": "0xa2",
                "friend": [
                  {
                    "uid": "0xa3",
                    "_Person": "*",
                    "title": "Delta"
                  }
                ],
                "_Person": "*",
                "title": "Charlie"
              }
            ],
            "_Person": "*",
            "title": "Bravo"
          }
        ],
        "_Person": "*",
        "title": "Alpha"
      }
    ]

Question:

Writing nested expand is fine, but is there a simpler way to achieve this?

Neo4J has something like:
MATCH (p)-[r:1..5]-(q) RETURN p, q

2 Likes
{
'_Person': '*',  'title': 'Alpha'
  'friend': {  '_Person': '*', 
     'title': 'Bravo', 'friend': {' _Person': '*',
       'title': 'Charlie', 'friend': {'_Person': '*', 'title': 'Delta'} } }
}

OBS. Never assign a UID manually, the UIDs must be generated by the Dgraph to avoid conflicts. Only if strictly necessary, if you want to update an existing Node.

I do not know exactly if I understood the question, but for now there is only this form, via GraphQL + -. There will be support for other languages such as Gremlin.

I always use uid to UPDATE a node. Actually UID was in my select statement, so I ended up printing it

More clarity of the question.

If I want to search
Me → friend1 → friend2 → … → friendN

then I have to write expand(_all_) N times right? and there is no easier way

I believe I already answered this question. I believe you will have something different from what we have today only when we support other Q languages. Today is the easiest.

If we were to use something like “expand(absolutely_everything”) this would lead to possible performance wastage. Ideally, you should use planned queries when you are on production. You can expand indefinitely, but you’d better do it in a planned way.

But tell me what your difficulty is? What does this blocks you in practice?

btw:

expand () serves to expand predicates, when you use "_all_" inside expand it will try to find all existing predicates of a Node and return them.

https://docs.dgraph.io/query-language#expand-predicates

Yes the question is answered,

Problem: I was basically trying to do a multi-level search of a node 10 levels deep the way other graph databases do (neo4j or gremlin) where 10 could be a parameter and it would traverse it.

I think the solutions is clear for me now, to use nested “expands”

In my point of view you can do this, you can use most Dgraph functions and directives at all levels of a query block.

First you do a wide search in Root, and in the others you use @filter with a pattern to your liking. You can use eq (Inequality), has (something), regexp, uid_in, AND, OR and NOT and so on.

e.g:


{
 AngelinaInfo(func:allofterms(name@en, "angelina jolie")) {
  name@en
   actor.film {
    performance.film {
      genre {
        name@en
      }
    }
   }
  }

 DirectorInfo(func: eq(name@en, "Peter Jackson")) {
    name@en
    director.film @filter(ge(initial_release_date, "2008"))  {
        Release_date: initial_release_date
        Name: name@en
    }
  }
}
1 Like

Take a look on this Matching queries · Issue #2267 · dgraph-io/dgraph · GitHub

Hey, see if this can help you too

1 Like