# 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

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