$mul operator in minimongo


#1

Hello !

I have a problem with minimongo. I want to update an integer field of my database. I want to use the $mul operator because I must multiplied the value by a multiplicator.
To do that I have read the documentation of mongodb and I found a solution :

PlayerEmployees.update({_id: currentUser.playerEmployeesId, 'employees.idEmployee': employeeId}, {$mul: {'employees.$.currentIncomeRate': parseFloat(multiplier)}});

And when I run my application, an error appear :

Exception while simulating the effect of invoking 'buyBonus' errorClass {error: 409, reason: "MinimongoError: Invalid modifier specified $mul", details: undefined, message: "MinimongoError: Invalid modifier specified $mul [409]", errorType: "Meteor.Error"} Error: MinimongoError: Invalid modifier specified $mul [409]
    at m.(anonymous function) (http://localhost:3000/packages/allow-deny.js?hash=28b7b02fffd8490f81f75fa9580e532e61473c0a:215:21)
    at http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3957:25
    at _.extend.withValue (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1077:17)
    at _.extend.apply (http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3948:54)
    at _callMutatorMethod (http://localhost:3000/packages/allow-deny.js?hash=28b7b02fffd8490f81f75fa9580e532e61473c0a:433:29)
    at update (http://localhost:3000/packages/mongo.js?hash=bc4cc4faf274ce28cefc812067aa65c0d4025ed4:673:19)
    at increaseRateOfEmployee (http://localhost:3000/app/app.js?hash=b915234a84cd634f77916aee1b4315f732092ee9:958:18)
    at buyBonus (http://localhost:3000/app/app.js?hash=b915234a84cd634f77916aee1b4315f732092ee9:931:21)
    at http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3957:25
    at _.extend.withValue (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1077:17)

I don’t understand. Is the $mul operator exist in minimongo ? If not how can I fix my problem ?

Sorry for my bad english, I’m french :smile:

Thank you !!


#2

$mul is not available in minimongo. You could use $set if you can precompute the new value:

PlayerEmployees.update({_id: currentUser.playerEmployeesId, 'employees.idEmployee': employeeId}, {$set: {'employees.$.currentIncomeRate': newIncomeRate}});

Alternatively, if you are doing this on the server (which seem sensible given the nature of the query), you can use the underlying NPM module to get access to $mul. Maybe something like this in a Meteor.method:

const rawCollection = PlayerEmployees.rawCollection();
const updateRate = Meteor.wrapAsync(rawCollection.update, rawCollection);
try {
  updateRate({_id: currentUser.playerEmployeesId, 'employees.idEmployee': employeeId}, {$mul: {'employees.$.currentIncomeRate': parseFloat(multiplier)}}));
} catch (err) {
  ...
}

#3

Hello,

Thank you for your answer robfallows ! I tried to use your second solution but the problem is my collection PlayerEmployees is declared in lib/collections/. This collection is available on both side because I also need it in client.

Now I have this error :
Exception while simulating the effect of invoking 'buyBonus' Error: Can only call rawCollection on server collections(…) Error: Can only call rawCollection on server collections

To call this function, the player (I code a game) click on a button and it call a Meteor.methods and in this method I want to use $mul. If I want to precompute the result, I must query the Database before :confused: . Is i possible to “cal” the field in the query like that :
{$set: {'employees.$.currentIncomeRate': 'employees.$.currentIncomeRate' * parseFloat(multiplier)}}

Thank you !


#4

It’s fine to have the collection defined in lib/. The important thing for the second solution is that the code for buyBonus must run on the server only.

If your method code is also in lib/ (or another shared folder), then you will need to wrap the code in a if (Meteor.isServer) block. Alternatively, put this method in a file in server/, so it’s not available to the client.


#5

Ok thank you very much now it works perfectly !