mauro
mauro

Reputation: 21

How to update Field by multiply Field value Mongodb

I try to update field with value in euro but something's going wrong.

db.orders.update({
    "_id": ObjectId("56892f6065380a21019dc810")
}, {
    $set: {
        "wartoscEUR": {
            $multiply: ["wartoscPLN", 4]
        }
    }
})

I got an error:

The dollar ($) prefixed field '$multiply' in 'wartoscEUR.$multiply' is not valid for storage.

WartoscPLN and WartoscEUR are number fields, and i'd like to calculate wartoscEUR by multiplying wartoscPLN by 4.

Sorry, maybe this is really easy but I'm just getting starting in nosql.

Upvotes: 2

Views: 4631

Answers (2)

chridam
chridam

Reputation: 103375

The $multiply operator can only be used in the aggregation framework, not in an update operation. You could use the aggregation framework in your case to create a new result set that has the new field wartoscEUR created with the $project pipeline.

From the result set you can then loop through it (using the forEach() method of the cursor returned from the .aggregate() method), update your collection with the new value but you cannot access a value of a document directly in an update statement hence the Bulk API update operation come in handy here:

The Bulk update will at least allow many operations to be sent in a single request with a singular response.

The above operation can be depicted with this implementation:

var bulk = db.orders.initializeOrderedBulkOp(),
    counter = 0;

db.orders.aggregate([
    {
        "$project": {                
            "wartoscEUR": { "$multiply": ["$wartoscPLN", 4] }
        }
    }
]).forEach(function (doc) {
    bulk.find({ "_id": doc._id }).updateOne({
        "$set": { "wartoscEUR": doc.wartoscEUR }
    });

    counter++;

    if (counter % 1000 == 0) {
        bulk.execute();
        bulk = db.orders.initializeOrderedBulkOp();
    }
});

if (counter % 1000 != 0) {
    bulk.execute();
}

Upvotes: 1

Philipp
Philipp

Reputation: 69663

The $multiply-operator is only used in aggregation. The operator you are looking for is $mul and it has a different syntax:

db.orders.update(
    {"_id" : ObjectId("56892f6065380a21019dc810")},
    { $mul: { wartoscPLN: 4 }
);

It is not necessary to combine it with $set, as it implies that semantic implicitly.

Upvotes: 3

Related Questions