使用Meteor 1.1.0.2和matb33:collection-hooks
软件包我遇到错误,试图在$set
挂钩中向modifier
对象添加before.update
由$inc
更新调用。
我在after.update
集合上有一个Invoices
摘要,因此当Invoices
个实例获得批准时,会增加 totalPurchases
个Products
个{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
答案 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;
}