Search code examples
mongodbmeanjs

Database modeling with mean.js and mongoose


I am classical developer who is normally developing relational DBs form my web applications.

I want to learn the new way and build an application with mean.js and mongoDB. I used yo generator from the meanjs.org to get started.

When I model my data I always fall back into the classic relational modeling. And I think this is not what the “new way” of app building is all about.

So my question is: What is he best practice to model my data model sample? My learning sample is an app in which you have a specific given list of music albums (like best 50 Jazz albums of all times) and the user checks in and rate the music. I have a CRUD module for adding and editing albums the user should listen to. This ends in an ordered list of albums.

I have a CRUD module for users, generated by the yo generator. A user now can see the list and mark the albums which he already heard. He should be able to give a rating and a comment.

So the question is: where to store the user listenTo info? In the relational world I would introduce a new foreign key table which has a relation from user to album and model the properties like rating and comment in the foreign key table. I don’t think this is how things should work in mongo DB world, does it?

I could add the user listenTo information to each album. I would have a list of users and comments on each album. Then, I need to ensure that if the list is requested, only the information of the current user is present. So I would have to filter on property on a sub-sub-document. Feels strange. Or, I could copy the album list for each newly created user but then I need to write code that changes the user’s object when I edit the original list.

What would you recommend?


Solution

  • When I think of Data Modeling, I break things down into the following relationships:

    1 <--> 1

    1 <--> Few/Many (A finite number, say a list of user's phone numbers)

    1 <--> Very Many

    The general rule of thumb with MongoDB is you should embed wherever possible. So for 1 <--> 1 and 1 <--> Few/Many if the document size is something small, you should embed the collection inside the user document.

    It's important to think about the use case here. If we want to track all songs that the user likes or listens to, this could potentially be hundreds or thousands, so we probably want to store this information in a separate collection and contain an indexed reference to the user there.

    In the case of tracking if a user listens to the song, I would probably structure it like this in your use case:

    {
        _id: ObjectID, // The identifier of the document
        user_id: ObjectID, // The user who listened to the song
        song_id: ObjectID, // The id of the song
        count: number, // The number of times the user listened
        rating: number, // The number of stars the user rated the song
        favorite: boolean, // If the user marked the song as a favorite
        last_listened: Date // The last time the user listened
    }
    

    With an index on { user_id: 1, song_id: 1 }.

    Here is a really good reference on how to approach your problem: https://docs.mongodb.com/manual/applications/data-models-relationships/