javascriptmongodbmeteorminimongo

JavaScript Object vs minimongo efficiency


My Meteor client receives data from the server and stores it in minimongo. This data is guaranteed not to change during their session, so I don't need Meteor's reactivity. The static data just happens to arrive by that route; let's just take that as a given.

The data looks like this:

{_id: 'abc...', val: {...}}

On the client, is it more efficient for me to look up values using:

val_I_need = Collection.findOne({id})

or to create a JavaScript object:

data = {}
Collection.find().fetch().map((x) => {data[x._id] = x.val})

and use it for look ups:

val_I_need = data[id]

Is there a tipping point, either in terms of the size of the data or the number of look ups, where the more efficient method changes, or outweighs the initial cost of building the object?


Solution

  • FindOne may be more efficient on larger datasets because it looks up using cursors where _id is an indexed key while your find().fetch() approach requires to get all docs and then iterate manually by mapping.

    Note, that findOne could also be replaced by .find({_id:desiredId}).fetch()[0](assuming it returns the desired doc).

    More on this in the mongo documentation on query performance.

    However, if it concerns only one object that is afterwards not reactively tracked, I would rather load it via a "findOne"-returning method from the server:

    export const getOne = new ValidatedMethod({
        name: "getOne",
        validate(query) {
            // validate query schema
            // ...
        },
        run(query) {
    
            // CHECK PERMISSIONS
            // ...
    
            return MyCollection.findOne(query);
    });
    

    This avoids using publications / subscriptions and thus minimongo for this collection on the current client template. Think about that pub/sub has already some reactivity initialized to observe the collection and thus eats up some computation somewhere.