TLDR:有没有办法可以有条件地更新集合中的Meteor Mongo记录,这样如果我使用id作为选择器,我想更新是否匹配,只有当版本号大于已经如果没有id匹配,则存在,还是执行upsert?
我遇到了服务器端Meteor Mongo集合更新的问题,看起来观察者中的added()函数回调是在upsert上触发的。
这就是我想要简单地做的事情。
我的meteor js应用程序启动,然后连接到端点,获取数据,然后将其插入到集合中。
collection.update({'sys.id': item.sys.id}, item, {upsert: true});
' sys.id'选择器检查该项是否存在,然后更新它是否存在,如果不存在则更新。
我有一个观察员监视上面的集合,然后在项目被添加/更新到集合时起作用。
collection.find({})。observeChanges({ 补充:this.itemAdded.bind(this), 已更改:this.itemChanged.bind(this), 删除:this.itemRemoved.bind(this) });
令我困惑的第一件事是,当应用程序关闭然后再次启动时,'添加()'观察集合时会触发回调。我希望发生的是change()回调被触发。
回到我原来的更新 - 在Mongo中是否有可能有条件地更新某些东西,所以你有选择器,然后是项目,但只在满足另一个条件时才执行更新?
// Incoming item
var item = {
sys: {
id: 1,
revision: 5
}
};
collection.update({'sys.id': item.sys.id, 'sys.revision': {$gt: item.sys.revision}, item, {upsert: true});
如果你看一下上面的代码,那要做的是尝试匹配sys.id,这很好,但是修订当然会有所不同,这意味着更新功能会将它看作一个不同的文档然后执行新的插入,从而创建重复的数据。
我该如何解决这个问题?
答案 0 :(得分:3)
对于你的主要问题:
您想要的是findAndModify
。首先,查找符合规范的文档,然后相应地更新。这是一个非常强大的想法,因为如果您在2个查询中执行此操作,则在更新之前可能会删除/更新您找到的文档。幸运的是,有人制作了一个包(我真的希望一年前存在!)https://github.com/fongandrew/meteor-find-and-modify
如果您在不使用findAndModify
的情况下执行此操作,则必须使用javascript查找文档,查看它是否符合您的条件,然后进行更新。在你的用例中,这可能会起作用,但总会有这样的情况,如果"在你的脑海里。
关于observeChanges
,每当本地minimongo收到一个文档时,就会调用添加的文件(它只是读取DDP告诉它的内容)。由于刷新会删除您的本地集合,因此您必须逐个添加这些文档。你可以做的是等到所有added
回调都被触发,然后运行你的服务器方法。在这样做的过程中,你会获得大量的补充,之后会有更多的变化。
答案 1 :(得分:2)
正如Matt K所说,你想要findAndModify。有一些问题需要注意: