在流星中用嵌入对象更新集合

时间:2016-02-23 12:58:37

标签: mongodb meteor insert-update meteor-collection2 simple-schema

我尝试在meteor的集合中添加JSON响应中的数据。不幸的是,我在Stack溢出时发现的所有东西都不起作用。在某些情况下,我得到了一个错误:

Exception in callback of async function: MongoError: Cannot update 'plugins' and 'plugins' at the same time

如果它没有返回错误,我的收藏中的对象仍然是空的,如:

"plugins": {}

下面的代码是导致空对象的原因,我希望有人可以帮助我。

我的收藏包含一个字段,其中包含一个包含多个对象的对象。我希望他们像这样

{ 
"_id" : "id", 
"name" : "DemoSite", 
"url" : "http://someurl.com", 
"createdAt" : ISODate("2016-02-10T17:22:15.011+0000"), 
"plugins" : 
    "Akismet": {
        "pluginName" : "Akismet", 
        "currentPluginVersion" : "3.1.7", 
        "newPluginVersion" : null, 
        "lastChecked" : "Thu Feb 18 2016 15:54:02 GMT+0100 (CET)"
    }, 
    "Random Plugin": {
        "pluginName" : "Random Plugin", 
        "currentPluginVersion" : "0.1.0", 
        "newPluginVersion" : null, 
        "lastChecked" : "Thu Feb 18 2016 15:54:02 GMT+0100 (CET)"
    }
}

如果我的HTTP.call没有错误,它将执行此操作:

var pluginData = result.data.plugins;
var dbPush = {};
if(pluginData != []){

    for (var key in pluginData){
        var obj = pluginData[key];

        var objKey = obj.Name;

        dbPush[objKey] = {
            'pluginName': objKey,
            'currentPluginVersion': obj.Version,
            'newPluginVersion': null,
            'lastChecked': new Date()
        };
        Items.update({_id: item._id}, {$set: {plugins: dbPush}});
    }
}

我的Simple架构中也有这个:

Items.attachSchema(new SimpleSchema({
name: {
    type: String,
    label: "Item name",
    min: 4,
    max: 100
},
url: {
    type: String,
    label: "Item url",
    autoform: {
        afFieldInput: {
            type: "url"
        }
    }
},
createdAt: {
    type: Date,
    optional: true,
    autoValue: function() {
      if (this.isInsert) {
        return new Date();
      }  else {
        this.unset();  // Prevent user from supplying their own value
      }
    },
    autoform: {
        afFieldInput: {
            type: "hidden"
        }
    }
},
plugins: {
    type: Object,
    optional: true
}
}));

修改

我尝试预定义所有对象,然后更新集合

dbPush["test"] = {
                    'pluginName': "test",
                    'currentPluginVersion': "1.0.0",
                    'newPluginVersion': null,
                    'lastChecked': new Date()
                  };
                  Items.update({_id: item._id}, {$set: {plugins: dbPush}});

2 个答案:

答案 0 :(得分:1)

我很确定这行代码:

Items.update({_id: item._id}, {$set: {plugins: dbPush}});

你的问题。您循环遍历每个插件并在每个插件的完全相同的项目上更新完全相同的MongoDB plugin属性。我想你想事先建立一个对象,只插入一次:

var pluginData = result.data.plugins;
var dbPush = {};
if(pluginData != []){

    for (var key in pluginData){
        var obj = pluginData[key];

        var objKey = obj.Name;

        dbPush[objKey] = {
            'pluginName': objKey,
            'currentPluginVersion': obj.Version,
            'newPluginVersion': null,
            'lastChecked': new Date()
        };
    }
    Items.update({_id: item._id}, {$set: {plugins: dbPush}});
}

现在,您正在循环一段时间并慢慢构建dbPush对象。

答案 1 :(得分:1)

我找到了解决办法。

这不是一个很好的解决方案,但Simple Schema不允许我在我的集​​合中拥有自定义对象。使用我的集合所需的所有内容都是文档here中的blackbox选项。

plugins: {
    type: Object,
    optional: true,
    blackbox: true
}

这将跳过plugins对象的验证,因此它会将数据存储在集合中。

感谢您的帮助!