I am trying to update a schema to add a new property field. I was hoping it would be as simple as adding the property to the schema with the updated field being accessible.
I have an existing schema
let userDrinkSchema = new mongoose.Schema({ new Schema
creator : {
type: mongoose.Schema.Types.ObjectId,
ref: 'user' // name of user file
},
caffeine: Number,
mgFloz: Number,
name: String,
size: Number,
updated_at: {
type: Date,
default: Date.now()
}
});
I need to add the id from this schema
const UserSchema = mongoose.Schema({
const User = module.exports = mongoose.model('User', UserSchema);
I am not sure how to add this property for each user. I followed this example Dealing with schema changes in Mongoose
The schema is now:
let DrinkSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
required: true,
default: null
},
caffeine: Number,
mgFloz: Number,
name: String,
size: Number,
imageUrl: String,
date: {
type: Date,
default: Date.now()
}
},
{
collection: 'drinkList'
});
Unfortunately for me the user is null as well
{
"_id":"58bba13bb7afeaa3180aa929",
"caffeine":422,"mgFloz":218.7,
"name":"10 Hour Energy Shot",
"size":1.93,
"url":"/caffeine-content/10-hour-eternal-shot",
"date":"2017-03-28T13:10:12.650Z",
"user":null
}
Is there a way to update the user field to get the user information? The schema that I am referencing is set up as
const SelectedDrinks = require('./userDrinks').schema;
const UserSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
},
caffeine_list: [SelectedDrinks]
})
I can see that mongodb adds an id to each user when they are created. this is what i am trying to access.
My backend route is configured in express. With postman I can get this to work becuase I have the user id. I am not sure how to get the correct user id inside of this route.
router.post('/addDrink', (req, res, next) => {
let newDrink = new UserDrinks({
creator: req.body.creator, // need id get user object id()
caffeine: req.body.caffeine,
mgFloz: req.body.mgFloz,
name: req.body.name,
size: req.body.size,
updated_at: req.body.updated_at
});
newDrink.save( (err) => {
if(err) {
res.send(err);
} else {
User.findOne({ _id: newDrink.creator}, (err, user) => {
user.caffeine_list.addToSet(newDrink)
user.save( function (err) {
if(err) {
console.log(err);
}else {
res.status(201).json(newDrink);
}
})
})
}
})
});
If I'm understanding this right, you're trying to replace the creator
field with the user
field. To accomplish this you'll need to do 2 things:
/addDrink
routedrinkList
collection1) When you create newDrink
, set user
instead of creator
:
let newDrink = new UserDrinks({
user: req.body.creator,
caffeine: req.body.caffeine,
mgFloz: req.body.mgFloz,
name: req.body.name,
size: req.body.size,
updated_at: req.body.updated_at
});
2) Update all UserDrinks
to rename the field:
UserDrinks.update({}, { $rename: { "creator" : "user" } }, { multi: true }, callback)
This will find all UserDrinks documents and rename the creator
property to user
.
A quick way to do this without having to create a new route for a one-time change is to create a temporary function for it under your express setup, run it locally, and delete/comment the code after so it doesn't run again. Ex:
function renameCreatorField() {
UserDrinks.update({}, { $rename: { "creator" : "user" } }, { multi: true }, function(err, data) {
if (!err) {
//success
}
})
}
renameCreatorField();
This will run immediately when your server starts up. Once it runs once you can delete it because the changes we made in (1) will ensure any future UserDrinks documents have the correct field set.
Of course, if you're just looking for a quick fix and this isn't a live application you can just do (1), clear out your database, and start fresh with correct documents. But that's not the way to learn. :)