Schema tips/best practices (Pinterest type app)

I am in the process of developing an application that has some similar functionality to an app such as Pinterest. I have started with some general ideas on how I would structure the data model/schema but I am not certain as to what is the best approach. The basic concept is that a user collects ‘ideas’ in ‘boards’. I aim to have unlimited hierarchy of sub-boards inside each board. Pinterest currently calls this ‘sections’ but do not allow more than 1 level of inheritance. As far as I know it is not possible to self-reference in fauna yet. So the ideal would be for ‘board’ to reference itself. Each board has both sub-boards and ideas and each idea can be connected to many boards. My main question is how to connect sub-boards to boards and to ensure that the ideas collection knows which board it is related to(board or sub-board). My guess is that I have to have some sort of containing class that contains the info on: the parent board(root board), the contained subboards and the contained ideas. Something like:

BoardContainer/BoardConnector
{
parent board: Board!, //the root board containing all the content
relation to many sub-boards/boards/sections: [board:{}, board: {}, …],
relation to many ideas: [idea: {}, idea: {}, …],
}

I have plans to be using different names of course but let’s say we’re using pinterest-like names. I started with this sketch a while back and it sort of works but it’s not adequate:

Now I have this template I’m working with:

Does any of you fauna experts have tips or best practices for how to model such an hierarchy?

Hi @Emil.

In the first schema, it looks like there is a one-to-many relation between the Board and sub-boards. So I don’t think the “link table” collection is necessary. If the ergonomics of that were an issue then maybe you could go back to that :man_shrugging:

But in the second one, I see the Ideas added to the link table. I like to think of this as an “edge with properties” as if it were in a graph db. It looks like that’s an important feature in the second schema, to qualify the relationship between boards, rather than the boards themselves.

I am not sure why Board has both the “root” board container and another field. Are you trying to have quick access to all the child and grandchild and great-grandchild boards? It sounds like keeping this in sync would be not be trivial.

1 Like

Thanks for replying ptpaterson.

You are right in this case but I see that it is not suitable for my needs now. Each board needs to be able to have many ideas and each idea has to be able to be connected to many boards.

I am definitely thinking about this in terms of a graph model now as you have suggested. The only thing I am confused about is how to know how the nodes are related in the hierarchy and how to traverse the hierarchy.

Basically a user clicks on the one of the root boards > gets sub-boards and ideas, clicks on sub-board > … repeat the cycle. So deeper in the hierarchy the user needs to see where in the hierarchy it is, it’s ancestors (child & grandchild ++ would be a nice to have).

So some thoughts I have:

  • could the board link type be used to contain the info on the parent and/or ancestors while it connects to both ideas collection + boards collection and is updated on writes?
  • could there be a completely different document that stores the total hierarchy of the boards that is updated when documents are added or removed?
  • is it possible to compute the hierarchy in a UDF that looks over the collections and finds the pattern instead of storing it and updating it in a document?
  • or should it instead be stored as an array of ancestors/children in each board document(which it looks like is the conventional way document db’s do it) and gets updated as in the first case?

I think this is a case where Fauna could really excel as compared to other alternatives and I am curious as to what is the easiest/best solution

Neat!

Something useful may be handling the connecting of stuff in custom resolvers. If all of the relationships are in separate types, then you can lock users out of editing directly and only grant permissions to the UDFs. Those UDFs could, in a single query, update/create/delete some connections, run traversals, and cache the relationship chain in the affected connections. Assuming writes happen less often than reads, this is good for performance.

Also there is no cascading updates provided by fauna API, so you may be able to piggy back on these UDFs to for example delete some child board and in so doing wipe out the remaining hierarchy. But if you just used default API you end up with orphaned boards.

Interesting, I will attempt to create custom resolvers that handles all the logic and only give users access to these endpoints. I’ll also add counters since boards and users needs boardCount and ideaCount etc. Would be cool to see common UDF solutions to these scenarios in the documentation or blogs. Like I said I think fauna can be good at doing things like this, and since hierarchy models etc are common it would be nice to have references for common modelling scenarios.