Sort by nested nodes values

Hi.

I simply can’t figure out how to return a list sorted on nested values and hope someone can explain how it can be done.
I know https://dgraph.io/docs/tips/#sort-edge-by-nested-node-values but the example doesn’t explain it a way I understand and can translate it into my solution.

So I have create a simple schema, with some sample data. See below.
The structure is simple. A RootLevel with n number of leafs.
In my query I do a filtering to ensure I only return 1 leaf pr. RootLevel. (@Filtering in the example is not correct but it works for the demo purpose)
The result I want to return should contain RootLevel and one Leaf node and be sorted based on Leaf.identifier and the order should be:

1 ident.
2 ident.
3 indet.
4 indet.

The returned order with my query is
1, 4, 3, 2 The uid order.

Hope someone can explain my the pattern to use, so I can get it to sort as expected.

Thanks in advance.

Lasse Nedergaard

#Schema

RootLevel.attributes: [uid] .
Leaf.identifier: string @index(exact) .
Leaf.note: string @index(fulltext) .
Leaf.parent: uid .
type Leaf {
	Leaf.identifier
	Leaf.note
}
type RootLevel {
	RootLevel.attributes
}

#Demo data.

{"set":[
    {"uid":"_:objatt","Leaf.identifier":"1 ident.","Leaf.note":"My note","dgraph.type":["Leaf"]},
    {"uid":"_:rootobj","dgraph.type":["RootLevel"],"RootLevel.attributes":[{"uid":"_:objatt"}]},
    {"uid":"_:objatt","Leaf.parent":{"uid":"_:rootobj"}}
  ]
}
{"set":[
    {"uid":"_:objatt","Leaf.identifier":"4 ident.","Leaf.note":"My note","dgraph.type":["Leaf"]},
    {"uid":"_:rootobj","dgraph.type":["RootLevel"],"RootLevel.attributes":[{"uid":"_:objatt"}]},
    {"uid":"_:objatt","Leaf.parent":{"uid":"_:rootobj"}}
  ]
}
{"set":[
    {"uid":"_:objatt","Leaf.identifier":"3 ident.","Leaf.note":"My note","dgraph.type":["Leaf"]},
    {"uid":"_:rootobj","dgraph.type":["RootLevel"],"RootLevel.attributes":[{"uid":"_:objatt"}]},
    {"uid":"_:objatt","Leaf.parent":{"uid":"_:rootobj"}}
  ]
}
{"set":[
    {"uid":"_:objatt","Leaf.identifier":"2 ident.","Leaf.note":"My note","dgraph.type":["Leaf"]},
    {"uid":"_:objatt2","Leaf.identifier":"1 ident.","Leaf.note":"not matching note","dgraph.type":["Leaf"]},
    {"uid":"_:rootobj","dgraph.type":["RootLevel"],"RootLevel.attributes":[{"uid":"_:objatt"}, {"uid":"_:objatt2"}]},
    {"uid":"_:objatt","Leaf.parent":{"uid":"_:rootobj"}},
    {"uid":"_:objatt2","Leaf.parent":{"uid":"_:rootobj"}}
  ]
}

#Query without sorting

{
  var(func: type(Leaf)) @filter(eq(Leaf.note, "My note"))
  {
    rootUid as Leaf.parent
  }

  results(func: uid(rootUid), first:10, offset:0) @cascade(RootLevel.attributes) {
    uid
    RootLevel.attributes {
      uid
      expand(_all_)
    }
  }
}

Something like this

{
      var(func: type(Leaf)) @filter(eq(Leaf.note, "My note"))
      {
        rootUid as Leaf.parent
      }

     var(func: uid(rootUid)) {
      RootLevel.attributes { Leafs as Leaf.identifier }
        Leafs2 as min(val(Leafs))
     }

      results(func: uid(Leafs2), orderasc: val(Leafs2))
        {
        uid
       RootLevel.attributes
          {
          uid
          expand(_all_)
        }
      }
}

Thanks Michael.

I Will try it out tomorrow.
I had almost the same solution but struggled with variable exception.
I find the syntax hard to understand. Can you explain why uid(Leafs2) returns RootLevel uid’s and not the id from Leaf.identifier.

Lasse

All variables contains always a map of UIDs and values. Leafs2 will contain the map of rootUid cuz Leafs2 is in the rootUid level.

In results(func: uid(Leafs2) you can use rootUid or Leafs2. Doesn’t matter.

I know. When I was learning GraphQL the learning curve was hard too. But it helped me out to learn DQL. So I think the learning curve of DQL is a bit complicated if you never touched any Graph logic before.

Hi Michael

That makes sense. Could it be an idea to add a section in the documentation explaining the “basic” as I guess I’m not the first one that didn’t get it the first time. (Perhaps it’s already there)

If we could explain the data structure “moving” through my example perhaps it would be easier to learn and understand. Just an idea.

Once again Thanks Michael it works.
My mistake was I tried to add the variable next to rootUid instead of adding another variable function.

1 Like