1

I'm writing an app which collects user's weight information every day. Im new in NoSQL databases world. So I would like to chose at the beginning the right schema.

The show case looks so: User say only one time the crucial data like how tall is or the age and after that user can measure its weight

Right now I wrote it like this:

var userSchema = new Schema({
    randomId: {type: Number, required: false, unique: true },
    name: String,
    userId:  {type: String, required: true},
    hight: Number,
    gender: String,
    waist: Number,
    age: Number,
    updated: { type: Date, default: Date.now }
});

how to store weight information every day?

Should I create a new model for weight with weight value and date?

var weightSchema = new Schema({
    name: String,
    userId:  {type: String, required: true},
    weightValue:{
       value: Number,
       updated: { type: Date, default: Date.now }
     }
});

or Sshould I update every time document userSchema?

Anna K
  • 1,666
  • 4
  • 23
  • 47
  • The only "right" way depends solely on how you intend to use the data. Embedded data will load much more quickly since it's already in the document, but referenced data is generally required where the number of "entries" to be embedded would be too large for that to be acceptable. If you're looking for a "best practice" rubber stamp, then there really just is not one. Do what suits your own application's usage patterns the best. – Neil Lunn May 09 '18 at 01:41

1 Answers1

1

Actually the data model design depends on the requirements of this software(How it use the data).

As my understanding, the user -> weight relationship is one-to-many mapping .If you just want to store user information and their weights and NO other additional requirements, your schema is ok.

So you store user data in user collection, one user for one document. And you have another collection to store user's weight data, multiple documents in this collection belongs to one user. When you want to fetch one user and his weight data, you have to query 2 times: one in user collection, another in weight collection.

But IMO, other aspects should be considered when designing the data model:

Performance

  • Data volume? Small pieces of data or a lot of data?
  • Read/Write percentage?
  • Is there any hot data user will access frequently?
  • ......

    Ease of use

  • Can I update/delete data easily?

  • .......

I will give some suggestions on different scenario below :

1. You consider the read performance and will NOT store too many weight records for one user

You can merge user schema & weights schema into one schema, the user schema holds an array to store all of the user's weight records. This is called the denormalized model that Mongodb suggests in common way. Your schema looks like:

(I have no JS programming enviroment in my PC, so not confirm this can be compile with no error. Just take it as reference.)

var weightSchema = new Schema({
    value: Number,
    updated: { type: Date, default: Date.now }
});
var userSchema = new Schema({
    randomId: {type: Number, required: false, unique: true },
    name: String,
    userId:  {type: String, required: true},
    hight: Number,
    gender: String,
    waist: Number,
    age: Number,
    weights: [weightSchema],  // Here are the weight records.
    updated: { type: Date, default: Date.now }
});
mongoose.model('user', userSchema);

Now you have only one collection to store user & their weight data. One document for one user. You can get some benifits:

  • data model that easier for human to understand
  • higher read performance, because mongodb needs to query only one collection now. You can get all data of one user by fetching one document. You can use $push when user add a new weight record. And you can fetch the oldest N or latest N weight records by $slice.

But at the same time you might encounter some problems:

  • If user add their weight records in very high frequency. The document size in user collection will grow to very large and fast. This will lead to moving the document's position in mongodb's storage when origin reserved space is not enough. This will NOT be good at write performance.
  • How can you calculate the average/top/... weight across all users ? Since the weight data are separated in each user, it is difficult to do this.

2. Your users have a lot of weight data and grows very fast. And you need to calculate average/top/... across users.

Please follow your origin design. Store data in two individual collections.

Conclusion

There are a lot of different modeling methods, all depends on your requirement. You can check out the Mongodb modeling guide: https://docs.mongodb.com/manual/core/data-modeling-introduction/

yellowB
  • 2,900
  • 1
  • 16
  • 19