在钩子中混合集合挂钩修改器操作会导致错误

时间:2015-07-24 18:36:08

标签: mongodb meteor

使用Meteor 1.1.0.2和matb33:collection-hooks软件包我遇到错误,试图在$set挂钩中向modifier对象添加before.update$inc更新调用。

我在after.update集合上有一个Invoices摘要,因此当Invoices个实例获得批准时,会增加 totalPurchasesProducts个{1}}集合实例如下:

if(Meteor.isServer) {
   Invoices.after.update(function(userId, doc, fieldNames, modifier, options) {

      if(modifier.$set && modifier.$set.approved === true) {
          //  Increment product.totalPurchases
          Products.update(doc.productId, {$inc: {totalPurchases: 1}});
      }
   });
}

然后是Products集合上的第二个挂钩,用于检查totalPurchases计数器是否超过了库存最大值,如果是,则设置一个标志{{1} 1}} instance Products对象所以当modifier实例上发生更新时,Products标志也会更新:

inventoryMaxReached

问题是if(Meteor.isServer) { Products.before.update(function(userId, doc, fieldNames, modifier, options) { if(modifier.$inc && modifier.$inc.totalPurchases) { // Check if total purchases is beyond max var newTotalPurchases = doc.totalPurchases + $modifier.$inc.totalPurchases; if(newTotalPurchases > TOTAL_INVENTORY_MAX) modifier.$set.inventoryMaxReached = true; } } }); } 返回错误,因为我正在向modifier.$set.inventoryMaxReached = true对象添加$set。我想出如果我将第一个钩子设为modifier而不是$set,那么第二个钩子就能正常工作。只有当所有操作都相同时,$inc对象才会满意。所以要做到这一点我改变了第一个钩子中的那一行:

modifier

为:

Products.update(doc.productId, {$inc: {totalPurchases: 1}});

我认为这解决了我的问题,但我发现这会产生第二个问题。如果的发票进入非常快var product = Products.findOne(doc.productId); Products.update(product.productId, {$set: {totalPurchases: product.totalPurchases + 1}}); 计数器将无法正确递增,因为挂钩异步解析的方式。 totalPurchases将解析为相同的值而不会实际递增。我在使用一堆product.totalPurchases + 1循环中的初始数据填充我的数据库时发现了这一点,这些循环执行得非常快。

但是,如果我在for挂钩的第一个版本中使用$inc,则Invoices计数器会更新正确。问题是我无法在totalPurchases更新触发的任何挂钩中执行$set,我需要这样做。

为了尝试解决这个问题,我实际上尝试在更新挂钩中进行更新。我改变了:

$inc

modifier.$set.inventoryMaxReached = true;

但是这会导致浏览器中的无限循环(我不知道为什么,因为我有Products.update(doc.id, {$set: inventoryMaxReached: true}});行来检查它是什么类型的更新。无论它是否有效,都需要hacky /尝试在其自己的if(modifier...)钩子内部的实例上调用update - 这可能是浏览器吓坏了的原因。这就是update对象的用途。

有谁知道怎么做?这是Mongo限制吗? modifier对象中只能存在一种操作吗?或者这是一个错误吗?

注意:所有内容都包含在modifier中,因为如果不这样做,增量实际上会被调用两次,一次在服务器上,一次在客户端上,并且它会在服务器上保存一个双倍增量的值。也不确定这是一个bug还是故意的。我在这里添加了一个问题:

https://github.com/matb33/meteor-collection-hooks/issues/140

编辑:我认为这可能是if(Meteor.isServer)中的错误。因为调用像这种混合操作的Mongo更新是完全可以接受的:

matb33:collection-hooks

1 个答案:

答案 0 :(得分:1)

您还有一个额外的$标志:$modifier.$inc.totalPurchases。它应该是modifier.$inc.totalPurchases

最后,您需要初始化modifier.$set,因为您只使用了$inc

if(newTotalPurchases > TOTAL_INVENTORY_MAX) {
  if (!modifier.$set) modifier.$set = {};
  modifier.$set.inventoryMaxReached = true;
}