简体   繁体   中英

Updating embedded documents in mongoose

I have a user and a premium schema. The premium one is embedded in user.

 const premiumSchema = new mongoose.Schema( { subscriptionID: { type: String, required: true, }, guild: { type: Object, default: {}, }, payment_id: { type: String, required: true, }, expiry: { type: Date, require: true, }, reminded: { type: Boolean, default: false, }, }, { collection: "premium" } );

 const userSchema = new mongoose.Schema({ discordId: { type: String, required: true, }, accessToken: { type: String, required: true, }, premium: { type: [premiumSchema], required: false, }, });

I am trying to update a value of my premium collection by:

 const user = await User.findOne({ "premium._id": new ObjectId(req.body.premiumId), }); const premium = user.premium.id(new ObjectId(req.body.premiumId)); premium.reminded = true; await user.save();

The Problem is that it updates the reminded attribute in my user.premium array but doesn't update it in the premium collection itself. Is there anything I am doing wrong?

You can use findOneAndUpdate method and positional operator to directly update your user.

Positional operator $ allows you to iterate through the array and update only the corresponding subdocument

const savedUser = await User.findOneAndUpdate(
  {_id: new ObjectId(req.body.premiumId)},
  {$set: {'premium.$.reminded': true}}
);

See doc: https://docs.mongodb.com/manual/reference/operator/update/positional/

This way you can update the subdocument within the User collection, but the value in the Premium collection will not be updated . This is because when you define the premium property within the Users collection you are telling mongoose (and mongodb) to save the object within the user collection itself. In this case there are no references between the two collections: the data will be saved only in the user collection, intended as subdocuments. You are just defining schema for child won't create a separate collection for the children in the database instead you will embed the whole child document in the parent (user).

Example data:

user1: {
  discordId: { 'abc' },
  accessToken: { 'token' },
  premium: {
    subscriptionID: { 'idSubscription' } 
    guild: { },
    payment_id: { 'idPayment' },
    expiry: { '2021-07-31T20:41:19.618+00:00' },
    reminded: { true }
  },
});

The two User and Premium collections remain completely separate. If you want to upgrade the Premium collection as well, you can do it using two different calls, one for User and one for Premium.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM