Sort all inbound and outbound edges by facets


(Una Chen) #1

I would like to find the top 3 closest friends, but the distance between two people is only saved with the unidirectional method in Dgraph because of exponential growth of predicate.

# (n= the number o people)
# save with the bidirectional method: Data capacity: n*(n-1)
<_:person1> <friend> <_:person2> (distance=0.5)
<_:person1> <friend> <_:person3> (distance=0.6)

<_:person2> <friend> <_:person1> (distance=0.5)
<_:person2> <friend> <_:person3> (distance=0.7)

<_:person3> <friend> <_:person1> (distance=0.6)
<_:person3> <friend> <_:person2> (distance=0.7)

# save with the unidirectional method: Data capacity: n*(n-1)/2
<_:person1> <friend> <_:person2> (distance=0.5)
<_:person1> <friend> <_:person3> (distance=0.6)
<_:person2> <friend> <_:person3> (distance=0.7)

Based on this storage method, I tried to find some solutions to sort all inbound and outbound edges by facets, but fail.
Therefore, here is the brute-fore approach I finally used.

# Firstly, query the top closest 3 friends in both directions.
{
   data(func: eq(name, "Alice")) {
     name
     nearests as friend @facets(orderasc:distance) (first:3){
       name
     }
     nearests_r as ~friend @facets(orderasc:distance) (first:3){
       name
     }
   }
}

# Secondly, sort it on my server which received the query result from Dgraph.
type Person struct {
  name
  Nearests    []*Person   `json:"nearests"`
  NearestsR   []*Person   `json:"nearests_r"`
}

resp.Nearests = append(resp.Nearests, resp.NearestsR...)
sort.Sort(resp.Nearests)
for _, n := range resp.Nearests[0:3] {
   # do something...
}

However, I think this method isn’t flexible.
For example, if I would like to search people whose top 3 closest friends’ name contain “Kiwi”, I need to query all people with top 6 (reverse+forward) closest friends; then sort and filter them on my server.

I would appreciate it if you have any advice for me.