Reputation: 2529
My schema definition as below. UserSchema has embedded Cards which in turn has many transactions..
var TransactionSchema = new Schema({
merchantName: String,
transactionTime: Date,
latitude: Number,
longitude: Number,
amount: Number
});
var CardSchema = new Schema({
cardIssuer: String,
lastFour: String,
expirationDate: String,
transactions : [TransactionSchema]
});
/*
* ...User Schema...
*/
var UserSchema = new Schema({
name: String,
email: { type: String, lowercase: true },
role: {
type: String,
default: 'user'
},
hashedPassword: String,
provider: String,
salt: String,
imageURL: String,
phoneNumber: String,
card: [CardSchema]
});
I want to add a transaction to the card already in the userschema but I am not sure how to do this in mongoose / mongodb
I identify the user and card as follows..
The api call goes through the auth middleware first
function isAuthenticated() {
return compose()
// Validate jwt
.use(function(req, res, next) {
// allow access_token to be passed through query parameter as well
if(req.query && req.query.hasOwnProperty('access_token')) {
req.headers.authorization = 'Bearer ' + req.query.access_token;
}
validateJwt(req, res, next);
})
// Attach user to request
.use(function(req, res, next) {
User.findById(req.user._id, function (err, user) {
if (err) return next(err);
if (!user) return res.send(401);
req.user = user;
next();
});
});
}
// This is update based on Neil's answer below...
exports.create = function(req, res) {
//var userItem = req.user;
//console.log(userItem._id);
//console.log(req.params.card);
Transaction.create(req.body, function(err, transaction){
console.log(transaction);
//id = mongoose.Types.ObjectId;
User.findOneAndUpdate({"card._id":id(req.params.card)},{
// $set : {
// role: 'user1'
// } ---- this update operation works!!
"$push": {
"card.$.transactions": transaction
} // -- this update operation causes error ...
}, function(err,user) {
// updated document here
console.log('err' + err + " user " + user) ;
return res.json(200, user);
}
)
// }
// })
})
};
Upvotes: 1
Views: 1486
Reputation: 151112
Adding new elements to an inner array is not difficult, as all you really need to do is match the position of the outer array to update in your query and then apply the positional $
operator in the update portion.
var transaction; // and initialize as a new transaction
User.findOneAndUpdate(
{ "card._id": cardId },
{
"$push": {
"card.$.transactions": transaction.toObject()
}
},
function(err,user) {
// updated document here
}
)
So that is straightforward for $push
operations. But be careful that you only ever want to $push
or $pull
as trying to update at a position of in "inner" array is not possible since the positional operator will only contain the first match, or the position in the "outer" array.
Upvotes: 3