Which side for add the @reverse is better?

like User has many Tweets, I can define an edge tweets: [uid] @reverse in User, or an edge author: uid @reverse in Tweet.

which side is better ? what is the difference ?

PS. Updated a bit.

It depends on the direction of your structure model. Dgraph is a “directed graph”.

For example author => tweets. So in that case the right edge to add the reverse index is the edge from author to “tweets”(so you can query for the author in the tweet level). Only if the direction were odd you would add the reverse index in the tweets to Author. e.g tweets => author. So the Author is the “child” of that tweet. Some devs like to use a convention with a dot in the edge that links both. e.g tweets.author: uid @reverse . or author.tweets: uid @reverse . So you kind know what is the direction.

The reverse index is good to find incoming edges. Very useful for “recurse delete” with upsert block.

The guideline I would use is this: what is the “main” object in your graph? In the twitter example, the “main” object would be a Tweet, and everything else can be considered an addition to it. So the field should be in the “main” object.

I use “main” in " " because most applications have more than one. In such cases, then you have to determine which is the one that is accessed the most. Put the field in that type.

Now this is all just rules of thumbs. They’re not hard and fast rules. Like @MichelDiz says, it depends on how you structure your data.

@MichelDiz is handle two-way relationships manually(without @reverse) suggested ?

I’m not Michel, but I think I can answer…

“Suggested” is a very loose term to use in this context because what might be suggested for a particular use case would not be suggested for another. There are best practices, but even then best practices are meant to be broken if a particular use case benefits from breaking the best practice.

Dgraph has done just what you call “suggested” in their GraphQL endpoint which doesn’t use the reverse directive at all, but instead manages pragmatically the two-way relationships when defined with the @hasInverse directive. This enables developers flexibility to drop either side of the relationship but keep the opposite. Again, this is the use case that Dgraph has developed GraphQL endpoint to solve, but your exact use case may be different.

Be aware that manually handling two-way predicates can be tricky and prone to bugs. Even with Dgraph’s graphql endpoint, it is possible to use DQL to muck up relationships that might not balanced.

Well, IMHO, the two-way edge is the best way to go. For several reasons. The first one is that the reverse index is just an index. It is just a “hacky indexation” that helps a lot in some query strategies. But is not recommended for practical graph modeling. Cuz reverse index has a little/limited context. With multiple edges, you can tell the whole story if you know what I mean.

I tend to use the example of a social media friendship system. With two edges you can say that User A has added User B and know if User B has accepted User A just by the context of two-way edge. Let’s say the edges are “ask.friendship: [uid] .” and the other “accepted.friendship: [uid] .”. With these two edges you can tell automatically if the user has new incoming friendships, and check what (comparing the two) friends needs to be accepted yet. If both edges are true. They are friends. And you can use, for example, Facets to capture when user A has added User B and when user B has accepted the friendship.

@MichelDiz thanks.
@amaster507 thanks on the same level .

@MichelDiz @amaster507
I read little more articles about this, in neo4j they said two-way edge is no necessary and a waste of space. of course like @MichelDiz said, in some scenario you should maintain edges separately, but in others the relationships looks so simple that it is no necessary .

I am confused about this, is there some article talk about the design pattern of dgraph? I really need it, thanks

I think there is one from @chewxy. And I was about to write a video about this. But I had some problems to solve and freeze the idea.

The post is here

1 Like

@MichelDiz expecting.
@chewxy good job.