Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropping a Mongo Database Collection in Meteor

Is there any way to drop a Mongo Database Collection from within the server side JavaScript code with Meteor? (really drop the whole thing, not just Meteor.Collection.remove({}); it's contents)

In addition, is there also a way to drop a Meteor.Collection from within the server side JavaScript code without dropping the corresponding database collection?

Why do that?

  • Searching in the subdocuments (subdocuments of the user-document, e.g. userdoc.mailbox[12345]) with underscore or similar turns out quiet slow (e.g. for large mailboxes).
  • On the other hand, putting all messages (in context of the mailbox-example) of all users in one big DB and then searching* all messages for one or more particular messages turns out to be very, very slow (for many users with large mailboxes), too.
  • There is also the size limit for Mongo documents, so if I store all messages of a user in his/her user-document, the mailbox's maximum size is < 16 MB together with all other user-data.

So I want to have a database for each of my user to use it as a mailbox, then the maximum size for one message is 16 MB (very acceptable) and I can search a mailbox using mongo queries.

Furthemore, since I'm using Meteor, it would be nice to then have this mongo db collection be loaded as Meteor.Collection whenever a user logs in. When a user deactivates his/her account, the db should of course be dropped, if the user just logs out, only the Meteor.Collection should be dropped (and restored when he/she logs in again).

To some extent, I got this working already, each user has a own db for the mailbox, but if anybody cancels his/her account, I have to delete this particular Mongo Collection manually. Also, I have do keep all mongo db collections alive as Meteor.Collections at all times because I cannot drop them.

This is a well working server-side code snippet for one-collection-per-user mailboxes:

var mailboxes = {};

Meteor.users.find({}, {fields: {_id: 1}}).forEach(function(user) {
    mailboxes[user._id] = new Meteor.Collection("Mailbox_" + user._id);
});

Meteor.publish("myMailbox", function(_query,_options) {
    if (this.userId) {
        return mailboxes[this.userId].find(_query, _options);
    };
});

while a client just subscribes with a certain query with this piece of client-code:

myMailbox = new Meteor.Collection("Mailbox_"+Meteor.userId());
Deps.autorun(function(){
    var filter=Session.get("mailboxFilter");
    if(_.isObject(filter) && filter.query && filter.options)
        Meteor.subscribe("myMailbox",filter.query,filter.options);
});

So if a client manipulates the session variable "mailboxFilter", the subscription is updated and the user gets a new bunch of messages in the minimongo.

It works very nice, the only thing missing is db collection dropping.

Thanks for any hint already!

*I previeously wrote "dropping" here, which was a total mistake. I meant searching.

like image 633
Moritz Walter Avatar asked Nov 26 '13 12:11

Moritz Walter


1 Answers

A solution that doesn't use a private method is:

myMailbox.rawCollection().drop();

This is better in my opinion because Meteor could randomly drop or rename the private method without any warning.

like image 60
Stephen Woods Avatar answered Sep 23 '22 19:09

Stephen Woods