How build a database that records user preferences over lists of items

Hello Everyone!
I’m new to MongoDB, and I’m still trying to understand what is the best way to do things.

In particular, I have the following problem:

Let’s assume that I have a list of books and a list of movies organized like this:

A. Books
– i. Fantasy
---- 1. Lord of the Rings
---- 2. Shannara
– ii. Crime
---- 1. Sherlock Holmes
---- 2. Agatha Christie

B. Movies
– i. Sci-Fi
---- 1. Dune
---- 2. I, Robot
– ii. Historical
---- 1. Ben Hur
---- 2. Lawrence of Arabia

And then I have a series of Users, and Users can select one category of books or movies, and they can rate all of them. So for isntance:

Mark:

  • A.i.1 = 5
  • A.i.2 = 3
  • B.ii.1 = 4
  • B.ii.2 = 4

Lucy

  • A.ii.1 = 1
  • A.ii.2 = 4
  • A.i.1 = 3
  • A.i.2 = 5
  • B.ii.1 = 5
  • B.II.2 = 3

What is the best practice to store such data in a MongoDB database?

Should I create a collection with the basic lists, and a second collection with the users, and then i will just copy and embed the collection each used select into their specific document, and attach the score to such copy?

Or is there a way to keep the actual lists of items in the lists collection and keep the rankings in the Users documents and somehow link the two, but without coping and embedding the lists in the documents of each users selecting them?

I sorry if this sounds like a silly questions, but as said, i’m quite new…

Hi @PaniniK,

Welcome to MongoDB community.

The question of schema design in MongoDB is a common topic when you start. One of the main questions you need to answer before deciding on schema is:

  1. How does your app access the data? Which data is commonly queried together. What is the update frequency of user data compared to preference?
  2. What kind of entities and relationship magnetuted do they have.
  3. You don’t hit any known antipatterns like to many collections and unbound arrays in documents,not crossing 16mb doc size.

Once we answer this we can get a better idea.

Just based on what you provided it sounds like the following schema might work:

//Collection users

{
UserId : .... ,
Username : ... ,
...
}

// Collection userPreferences

{
User : {
UserId, 
Username }
Category : "books",
Fantasy : [ {name : "..." , Rating : 1}, {name : "..." , Rating : 1}]
...
}

You can update the arrays to be sorted based on calculate rating with $each.

Now what I am not sure is if the rating is avg across users or each rating is for one user only?

Thanks
Pavel