Meteor Mongo Collections $pull annoyances
Situation
Recently we ran into the situation were we wanted to remove an item from an embedded Array of Objects in a Meteor Mongo Collection - on the server
Easy task at first glance because you’d expect to be able to use Mongo’s inbuilt $pull option in a Collection.update()
query, right?
|
|
Using this on the server lead to the following error however:
Error: Update parameter cannot have both modifier and non-modifier fields.
Complication
Meteor provides Mongo access under the hood via a package called MiniMongo.
The default implementation of Meteor’s MiniMongo implementation of Collection.update()
does not allow for the usage of $pull our this particular way.
In the Meteor Docs we can read that:
$pull in modifiers can only accept certain kinds of selectors.
So, I guess that our selector was not one of them…
Solution 1 (server)
Luckily - on the server - we have access to the native mongodb driver in the form of Collection.rawCollection()
.
This gives us access to all kinds of helpful Mongo methods that have not been implemented in MiniMongo (yet).
This was a suitable solution for us as for the specific method, it was a server only method that was not stubbed on the client for latency compensation.
Using the following pattern thus - gives us the desired result:
|
|
Solution 2 (server + client)
Since, on the client you don’t have access to Collection.rawCollection()
you would run into an error on the client when using the above approach in client code, or in a latency compensated Method call that executes on client & server.
You could fall back on a library like underscore of lodash to reject the documents you would want to have ‘pulled’:
|
|
Note: Please bear in mind that concurrency / read/write concern could become a problem here. Use wisely!