更新 collection 并在流星中嵌入 objects

updating collection with embedded objects in meteor

我试图在我的 collection in meteor 中添加来自 JSON 响应的数据。不幸的是,我在 Stack overflow 上找到的所有东西都不起作用。在某些情况下,我收到如下错误:

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

如果没有 return 错误,我的 collection 中的 object 将保持为空,例如:

"plugins": {}

下面的代码是导致空 object 的原因,我希望这里有人能帮助我。

我的 collection 由一个字段组成,该字段有一个 object,里面有多个 object。我希望他们是这样的

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

我的简单架构中也有这个:

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

编辑

我尝试预定义所有 object 然后更新 collection

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

我很确定这行代码:

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 对象。

我找到了一个修复程序。

这不是一个很好的解决方案,但简单模式不允许我在 collection 中使用自定义 object。使它与我的 collection 一起工作所需的全部是在文档 here.

中找到的黑盒选项
plugins: {
    type: Object,
    optional: true,
    blackbox: true
}

这将跳过对 plugins object 的验证,因此它将数据存储在 collection。

感谢大家的帮助!