代码之家  ›  专栏  ›  技术社区  ›  Hijlco Lankhorst

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

  •  2
  • Hijlco Lankhorst  · 技术社区  · 8 年前

    我试图在流星中的集合中添加来自JSON响应的数据。不幸的是,我在堆栈溢出中发现的所有东西都不起作用。在某些情况下,我返回了一个错误,如:

    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。调用没有错误,它将执行以下操作:

    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 回复  |  直到 8 年前
        1
  •  1
  •   Stephen Woods    8 年前

    我很确定这行代码:

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

        2
  •  1
  •   Hijlco Lankhorst    8 年前

    我找到了解决办法。

    这不是一个很好的解决方案,但SimpleSchema不允许我在集合中有自定义对象。要使这与我的收藏一起使用,只需使用文档中的blackbox选项 here .

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

    这将跳过对 plugins 对象,以便将数据存储在集合中。

    谢谢你的帮助!