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.