So here is my situation: I am building an expense tracker software, in which each expense belongs to one category and one or more tags and optionally each tag belongs to a category. This is quite straight forward. but here where it gets interesting. Each user can edit categories or merge them with other categories or even merge them with tags or delete them. so I can see 2 approaches to implement this:

  1. Save each category independent of any user information and then embed a document in each user document containing all user's categories id, and then when a user want to change a category name: A. if there is already a category with that name just update the categories subdocument in user document, that is to remove the old id and add the new one and then find all the expenses of the user associated with that category and change their category as well. B. If the category name is new, create a new category and add it to user's categories and then update the corresponding expenses.

    const categorySchema = new mongoose.Schema({
        name: { type: String, unique: true }
  2. Treat categories and tags like expenses, what i mean is to save each category and tag with user information, so each user has its own set of categories and tags to play with.

    const categorySchema = new mongoose.Schema({
        name: { type: String },
        user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }

I don't like the second approach because there's too much duplication, There are some default categories and tags, so I would end up repeat creating the same category only with deferent user. I don't like the first approach because a simple operation like changing a category or tags name would cause so much computation.

and also if I choose the first approach what happens to tag association with categories? if a user change the category associated with a tag it would reflect the change to other users as well.

So my questions are: Is there a better solution? If not, which of the above approach is better and why?

closed as primarily opinion-based by LowlyDBA, RDFozz, Erik Darling, hot2use, mustaccio Jan 12 '18 at 14:20

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.


Friend ... There is not a better solution!

There are trade-offs, if you replicate the data you will perform better in queries, but you will have a relatively large job to keep the data current and consistent.

On the other hand, a relational-like model will bring its benefits in the Inclusion, Change, and Exclusion operations of the data. But it will cause problems in the queries.

According to what I understood from your model, have you ever thought about making a hybrid model? Maybe for you it is the wisest solution.

To help you with the decision, I advise you to:

  • Define which are the predominant operations Inclusion, Exclusion and Alteration or queries. Because if queries are prevalent, no problems with data redundancy. If other operations are predominant you need to think about how you will keep the data consistent (if you use version 3.6 it is easier to monitor when a data is changed look for the Change Streams feature);
  • Make a logical data model taking into consideration the data and your relationships do not consider the operations; redundancies
  • Compare the models to make it easier to do the analysis.

I believe that by visualizing the data you will be able to reach a better consluence. I point out that MongoDB is phenomenal, but you need to design your solution to have all the benefits!

I sincerely hope I have been able to help you.

Not the answer you're looking for? Browse other questions tagged or ask your own question.