How to update a field universally in MongoDB?

Viewed 56

I have 1 database: database. There are 2 collections in database: users, posts. Mongoose schemas: User, Post.

Here is a user:

{
  "_id": "5f0e99abef55507333f0c34ef45",
  "name": "David",
  "email": "david@email.com"
}

I can post something with the user and save it to the posts collection.

let user = await User.findById(req.user.id);
let newPost = new Post({
  post: req.body.post,
  by: user, // this is the important part
});
await newPost.save();

And here is the new post with a by field:

"_id": "3287327392392293243434",
"post": "this is david's post",
"by": {
  "_id": "5f0e99abef55507333f0c34ef45",
  "name": "David",
  "email": "david@email.com"
  }

And then I update my profile to this:

{
  "_id": "5f0e99abef07333f0c34ef45",
  "name": "Dave", // change from David to Dave
  "email": "david@email.com"
}

After this I send a get request to get all posts:

[{
"_id": "3287327392392293243434",
"post": "this is david's post",
"by": {
  "_id": "5f0e99abef07333f0c34ef45",
  "name": "David",
  "email": "david@email.com"
  },
}]

The problem is that the by field has the same object, nothing was updated here after I updated my name. It's still David and not Dave. I know that when I updated my profile I only updated the user, not the post. I could write the code like to update the post too, but if I have many posts, many comments, and I change my name, image, biography or other fields regularly, then way too many things happen when updating my profile (and maybe thousands of posts).

What I want is that when I update my user profile, is there a way to be updated across this MongoDB database? Like I want that by field in the post to show my updated name.

Is it something to do with the user schema?

1 Answers

The problem you are facing is because you are saving duplicate data of user in your database, once in user collection and once in post collection. You shouldn't have duplicate data in your database.

Instead of saving complete user data in by field with each post document, only save user's id and link both user document and post document using SchemaType.prototype.ref(). This way, you won't have duplicate data in your database and the problem you are facing right now will be solved. Post schema should like:

let postSchema = new mongoose.Schema({
  post: String,
  by: { type: Schema.Types.ObjectId, ref: 'User' } // link between post and a user
});

and User schema should look something like:

let userSchema = new mongoose.Schema({
  name: String,
  email: String 
});

Keep in mind that value of ref in post schema should be same as the string that you pass as first argument to mongoose.model() function. For example, if in user schema file, you call mongoose.model('User', userSchema) then the value of ref property in post schema should be 'User'

Take a look at Mongoose - Populate(). This function will allow you to get the user data that is linked with any particular post document.

Related