Optimisation: canteen management app

TL;DR:
I’m making an app for a canteen. I have a collection with the persons and a collection where I “log” every meat took. I need to know those who DIDN’T take the meal.

Long version:

I’m making an application for my local Red Cross.

I’m trying to optimize this situation:

  • there is a canteen at wich the helped people can take food at breakfast, lunch and supper. We need to know how many took the meal (and this is easy).

  • if they are present they HAVE TO take the meal and eat, so we need to know how many (and who) HAVEN’T eat (this is the part that I need to optimize).

  • When they take the meal the “cashier” insert their barcode, the program log the “transaction” in the log collection.

Actually, on creation of the template “canteen” I create a local collection “meals” and populate it with the data of all the people in the DB, (so ID, name, fasting/satiated), then I use this collection for my counters and to display who took the meal and who didn’t.
(the variable “mealKind” is = “breakfast” OR “lunch” OR “dinner” depending on the actual serving.)

Template.canteen.created = function(){
  Meals=new Mongo.Collection(null);
  var today= new Date();today.setHours(0,0,1);
  var pers=Persons.find({"status":"present"},{fields:{"Name":1,"Surname":1,"barcode":1}}).fetch();
  pers.forEach(function(uno){
    var vediamo=Log.findOne({"dest":uno.codice,"what":mealKind, "when":{"$gte": today}});
    if(typeof vediamo=="object"){
      uno['eat']="satiated";
    }else{
      uno['eat']="fasting";
    }
    Meals.insert(uno);
  });
};

Template.canteen.destroyed = function(){
   meals.remove({});
};

From the meal collection I estrapolate the two colums of people satiated (with name, surname and barcode) and fasting, and I also use two helpers:

  fasting:function(){
    return Meals.find({"eat":"fasting"});
  }
  "countFasting":function(){
    return Meals.find({"eat":"fasting"}).count();
  }
//same for satiated

This was ok, but now the number of people is really increasing (we are arount 1000 and counting) and the creation of the page is very very slow, and usually it stops with errors so I can read that “100 fasting, 400 satiated” but I have around 1000 persons in the DB (probably because subscription latency?).

I can’t figure out how to optimize the workflow, every other method that I tried involved (in a manner or another) more queries to the DB; I think that I missed the point and now I cannot see it.
I’m not sure about aggregation at this level and inside meteor, because of minimongo.

This project is made with an old version of meteor so with blaze and iron:router, I planned to upgrade to react (and his router) but I haven’t enough react experience to migrate everything.

+1 if the solution is compatibile with aleed:tabular

Thank you everyone!

Hi there,

I have just created a package for that kind of scenario. Check it out at https://github.com/thebarty/meteor-denormalized-views

This package is really intresting, and I see how i can use it to trow data
at aldeed:tabular, but I cannot see (maybe can you make me an example?) how
to use your package in an efficent manner to obtain the informations about
those who didn’t take the meal…

Maybe a little bump can help, i still cannot figure out a clever way to have the list of people that have not eat. I have to change my code anyway so be fantasious!