Create tree view

I recently started using Dgraph and now I have a question on how to query the following. This example is a simplified version of what I want to achieve, but I suppose it will help me getting started.

Let’s say I have a dataset with persons and each person has multiple friends. And of course, each friend is also a person. We also want to know since when a person is a friend. I don’t know what would be better, but the latter could either be done with an extra attribute/predicate for each friend, or with a facet. So, the mutation would look something like this as JSON:

[{
   name: person 1
   friends: [
     {
         name: friend1,
         friend_since (this could also be a facet)
     },
     {
         name: friend2,
         friend_since
     },
     {
         name: friend 4,
         friend_since
     }]
},
{
   name: person 2
   friends: [
     {
         name: friend1,
         friend_since (this could also be a facet)
     },
     {
         name: friend3,
         friend_since
     }]
}]

What I want to achieve is a tree view where I could click on a persons name, for example friend 1, and show ALL the friends for each person that also has friend 1. So, selecting friend 1 would show friend 2 (person 1) and friend 3 (person 2). But selecting friend 2 would show friend 1 and friend 4 but not friend 3.

Unfortunately, it doesn’t stop there. What I ultimately want to achieve is that I could start with friend 1, which would show friend 2-4. But after that, I would want to select friend 1 AND friend 2, which only shows friend 4 because person 2 does not have both friends 1 and 2. This could go on forever.

Of course I could do a query for each level. But at first I want to let Dgraph do most of the work and besides, I mentioned the friend_since. This one is important because I only want the friends with a greater friend_since than the selected once. If for example friend 2 was a friend of person 1 before friend 1 was. Selecting friend 1 should not show friend 2 in the result.

It might be useful to know that the result would look something like this:

{
   first_selection {
      name: friend_1
      second_selection: {
         name: friend_2 
         friends: {
             [{name: friend_4}, {name: friend_x}, ..]
         }

   } 
}

So, it isn’t necessary to show the friends (and their counts finally) for each selection/level, but only for the deepest level.

In summary, I have two questions:

  1. Should the friend_since be a facet on an edge or just a predicate?
  2. Is it possible what I’m asking for or should just do multiple queries and if it isn’t possible in 1 query only is there maybe a way to create such a tree view.

I prefer querying with DQL and I’m using the latest Dgraph docker image.

I hope you can help me. Thanks in advance!

Information about a relationship should be recorded between the two entities. Facets are the best choice. But you can also have an intermediate list of entities. e.g. You have the entity “Person”, “RelationShip”. And you wanna connect Two individuals. It would be like Person => RelationShip => Person. And in the RelationShip entity, you record all infinity possible information about the relationship itself. This is useful if you need to query for kinds of relationships. As facet isn’t a First-class citizen you can’t use that information proactively.

I don’t get what you are trying to achieve. Maybe I’m just tired in this afternoon. Are you asking for suggestions to create a graph view?

Thanks for your response!

I will try to rephrase my question. What I’m trying to achieve is the following: I have a database with multiple persons and each persons has friends. Now I want the number of persons (or just a list of all the persons) which all have friends A, B and C. So, if some person is only befriended with person A and B, this person should not be taken into account.

I understand that this is a simple query where one could just add multiple filters. But, my problem is I also want to filter that friend A has a longer relationship than friend B, and friend B longer than friend C. That’s why I needed the friend_since facet. For example, if I want to check if a single person has both friends A and B, but friend B was befriended with this person before friend A, it should return false.

Of course, I could retrieve all persons having friends A,B,C and then loop over each person and check if the friend_since relationship of friend A is lower than friend B, and friend B lower than friend C. That would take quite a long time if there are a lot of persons to go over. But I was wondering if that could also be done in DQL. And if so, do you have an example query?

Thanks for your time!