【问题标题】:Meteor, mongodb - canteen optimizationMeteor、mongodb——食堂优化
【发布时间】:2016-08-06 11:10:51
【问题描述】:

TL;DR: 我正在为食堂制作应用程序。我和这些人有一个集合,还有一个我“记录”每块肉的集合。我需要知道那些没有吃饭的人。

加长版:

我正在为当地红十字会提出申请。

我正在尝试优化这种情况:

  • 有一个食堂,被帮助的人可以在早餐、午餐和晚餐时吃东西。我们需要知道有多少人吃了这顿饭(这很容易)。

  • 如果他们在场,他们必须吃饭,所以我们需要知道有多少(以及谁)没有吃(这是我需要优化的部分)。

  • 当他们用餐时,“收银员”插入他们的条形码,程序将“交易”记录在日志集合中。

实际上,在创建模板“食堂”时,我创建了一个本地集合“餐食”,并用数据库中所有人的数据填充它(所以 ID、姓名、禁食/饱食),然后我使用它收集我的柜台,并显示谁吃了饭,谁没有。 (变量“mealKind”是 = “breakfast” OR “lunch” OR “dinner”,具体取决于实际服务。)

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({});
};

从膳食集合中,我将吃饱(带有姓名、姓氏和条形码)和禁食的两列人分开,我还使用了两个助手:

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

这没关系,但现在人数确实在增加(我们大约有 1000 人并且还在增加),页面的创建非常缓慢,通常它会因错误而停止,所以我可以读到“100 禁食, 400 人吃饱了”,但我在 DB 中有大约 1000 人。

我不知道如何优化工作流程,我尝试过的所有其他方法都涉及(以某种方式)对数据库的更多查询;我认为我错过了重点,现在我看不到它。 由于 minimongo,我不确定这个级别和流星内部的聚合。

虽然制作这个服务器端而不是客户端很聪明,但这里的问题是如何在不循环所有人员集合的情况下区分“禁食”和“饱食”。

+1 如果解决方案与 aleed:tabular 兼容

【问题讨论】:

  • 看起来您完全依赖客户端 minimongo DB 进行Meals 跟踪?如果您的浏览器崩溃/意外关闭会怎样?
  • 是的,我完全依赖这个。如果浏览器在重新进入应用程序时崩溃,则会触发 onCreated 事件并重新创建本地集合。服务器支持的集合更难维护,因为我每天都必须清除它......
  • 对不起,误解了这个问题,当收银员插入交易时,我当然会在 Log 集合中插入一个文档。所以我对饭菜有一个长期的跟踪。如果浏览器崩溃,它可以在不丢失任何数据的情况下恢复。

标签: javascript mongodb meteor optimization aldeed-tabular


【解决方案1】:

编辑

我仍然不确定是什么导致了您的性能问题(客户端内存/minimongo 中有太多东西,对它的调用太多?),但您至少可以尝试不同的方法,更传统的是基于您的服务器。

顺便说一句,你没有提到你如何显示你的数据,或者你是如何得到错误读数的已经服务/丢失的Persons

如果您正在构建经典的 HTML table,请注意浏览器难以渲染超过几百行。如果是这种情况,您可以实现客户端表格分页/无限滚动。例如查看 jQuery DataTables 插件(基于 aldeed:tabular)。跳过构建实际 HTML table 的步骤,直接使用 $table.rows.add(myArrayOfData).draw() 填充,以避免浏览器限制。


原答案

我不完全明白您为什么需要将您的 Persons 集合复制到客户端 Meals 本地集合中?

这要求您首先所有文件从服务器发送到客户端Persons(如果您的服务器连接良好/本地,这可能不会有问题。您可能还有autopublish打包,所以你已经看到了惩罚),然后克隆所有文档(检查你的 Logs 集合以检索任何以前的段落),有效地使你的内存需求加倍。

您的服务器和/或远程数据库的速度是否足以证明您需要在本地(客户端)执行所有操作?

如果您打开多个“收银员”/客户端浏览器,问题可能会大得多,它们的 Meals 本地集合将不会同步。

如果您的服务器-客户端连接良好,则没有理由在客户端做所有事情。 Meteor 将自动缓存所需的内容,并提供乐观的数据库修改以保持快速的用户体验(如果您的代码结构正确)。

  • 使用aldeed:tabular 包,您可以通过“页面”轻松显示您的Persons 大表。
  • 您还可以使用dburles:collection-helpers 将其与您的Logs 集合链接(IIRC 在aldeed:tabular 主页上有一个示例)。

【讨论】:

  • 你的解释很详细,但可能我没有很好地解释这一点。我在服务器端做了一些工作,但每次有人打开应用程序时,服务器都无法承受超过 900 个查询。问题是有效地告诉谁没有吃饭(我只有一个查询中的所有其他信息)。我会查看 collection-helpers 文档,谢谢你的帮助。
  • 可能对 Meteor 的工作原理存在一些误解,或者我仍然不明白您的问题。在您共享的代码中,您的应用在填充 Meals 本地集合时已经进行了 900 db 查询,因为它会为每个 Persons 文档轮询 Log 集合。现在,如果您在当前日期发布了 Log 文档(或者您启用了 autopublish),您的客户端不会轮询服务器数据库,而是轮询其本地缓存 (minimongo)。
  • 是的,我的代码已经进行了 900 次查询,我询问是否有办法(重构代码)来避免或优化这个阶段。事实上,我使用客户端正是因为这样查询是针对 minimongo 而不是针对服务器的,但是这种方式也很慢(恕我直言,使它成为服务器端只会让它变慢,也许我错了) .我的问题是我写了一段糟糕的代码,我需要帮助来重新关注如何以聪明的方式完成相同的任务。
  • 回答您的编辑:我想使用 aldeed:tabular 但无法使用此设置。实际上,我只是将 div 添加到一个引导列中,这并不完美(实际上我询问了修改代码的建议)。我得到了错误的数字,因为我使用的计数器(countFasting)显示大约 2-300 人,但至少有 1500 人注册。我实际上禁用了该功能,但我仍在测试一些变化,因为我们需要这个数字。我认为要做的就是将这个问题从 O(n) 减少到 O(1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 2015-01-21
  • 2015-01-09
  • 2015-03-06
  • 2021-11-10
相关资源
最近更新 更多