Reputation: 364
I am running into an update problem using Mongoose, below is the schema definition. For example sake, below I would like to udpate the price of a car by multiplying the number of tires by 500:
car.js =
var mongoose = require('mongoose');
module.exports = mongoose.model('car', {
make : {type:String},
model : {type:String},
num_tires: {type:Number, default:0}
price : {type:Number, default:0}
});
updateCost.js =
var Car = require('car');
Car.update(
{make: 'Honda'},
{price: {$multiply: ['$num_tires', 500]}},
{multi: true},
function(err) {
console.log("Thar's an err", err);
});
The error I am receiving is: "Can't use $multiply with Number".
Is there a way around the schema definition Number to update the price? Thanks everyone for their time.
Upvotes: 1
Views: 1311
Reputation: 103475
You cannot reference the current document's properties from within an update(). You'll either have to iterate through all the documents and update them or use aggregation with the $multiply
expression as an arithmetic operation in aggregation within $project
pipeline to multiply the num_tires
field with the constant:
db.cars.aggregate([
{
$match: {
make: 'Honda'
}
},
{
$project: {
make: 1,
model: 1,
num_tires: 1,
price: {
$multiply: [ "$num_tires", 500 ]
}
}
}
])
Or you can update your schema to include an arbitrary field unit_price: {type: Number, default: 500}
which you can then use as $multiply: [ "$num_tires", "$unit_price" ]
in the $project
pipeline.
Another alternative is to iterate through all the matched documents and update using save method like this:
var Car = require('car');
Car.find({make: 'Honda'}).snapshot().forEach(
function (e) {
// update document, using its own properties
e.price = e.num_tires * 500;
// remove old property
delete e.price;
// save the updated document
Car.save(e);
}
);
Or using the $set
operator:
var Car = require('car');
Car.find().forEach(
function (elem) {
Car.update(
{
_id: elem._id,
make: "Honda"
},
{
$set: {
price: elem.num_tires * 500
}
},
{multi: true},
function(err) {
console.log("There's an error ", err);
}
);
}
);
If you had a default value for the price which is equal to the num_tires
, then you may want to just update the price
field without referencing another field in the same document, use the $mul
operator:
var Car = require('car');
Car.update(
{make: 'Honda'},
{$mul: {price: 500}},
{multi: true},
function(err) {
console.log("There's an error ", err);
}
});
Upvotes: 3