如何upsert MongoCollection但保留一些值?

时间:2017-03-28 12:32:37

标签: javascript mongodb meteor collections

嗨, 我不知道如何为它写好标题但我确定你会明白

所以当用户点击一个按钮时,我试图在我的Mongo集合上设置2个字段但是每60sc我有一个正在运行的方法,并且是谁:

  upsertCollectionMachines = Meteor.bindEnvironment(function() {
      machinesCount = 0;
        var protocol;
        var port;
        Machine.list({
            inspect: true
        }, Meteor.bindEnvironment(function(err, machines) {
            if (typeof machines === "undefined") {
                console.error("Impossible to access 'machines' from 'Machine.list:  '" + err);
            } else {
                machines.forEach(Meteor.bindEnvironment(function(machineInfo) {
                    machinesCount += 1;
                    if (machineInfo.url != null) {
                        var urlToArray = machineInfo.url.split(":")
                        port = urlToArray[urlToArray.length - 1];
                        protocol = "https";
                    } else {
                        port = "2376";
                        protocol = "https";
                    }
                    InfosMachines.upsert({
                        nameMachine: machineInfo.name,
                    }, {
                        nameMachine: machineInfo.name,
                        stateMachine: machineInfo.state,
                        ipAddr: machineInfo.driver.ipAddress,
                        port: port,
                        protocol: protocol
//here I want to add isUsed: false,  
//whoUseIt: "", but I think if I set isUsed true --> after 60s it will be false again right ?
                    });
                }));
                if (apiKeyGenerated == false) {
                    getTheAPIKeyGrafana(function(err, res) {
                        if (!err) {
                            apiKeyGenerated = true;
                            updateDashboard();
                        } else {
                            console.error(err);
                        }
                    });
                }else{
                  updateDashboard();
                }
            }
        }));
    })

重要部分是InfosMachines.upsert()。现在我想设置这样的2个字段:

'lockTheMachine': function(nameMachine, nameUser){
        InfosMachines.upsert({
            nameMachine: nameMachine,
        }, {
            nameMachine: nameMachine,
            isUsed: true,
            whoUseIt: nameUser
        });
        //upsertCollectionMachines();
        console.log(nameUser +" has locked the machine: " + nameMachine);
        },

但首先它看起来并不喜欢它将2个字段添加到集合中,其次60s间隔方法会删除它们吗?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

在你的问题中完全遵循你想要做的事情有点难,但我认为我得到了它的主要要点。

基本上,您希望lockTheMachine()函数upsert仅设置nameMachineisUsedwhoUseIt字段,并且您只希望upsertCollectionMachines()设置{更新时只有{1}},stateMachineipAddrport个字段,并且只在插入时将protocolisUsed设置为默认值?

你应该可以使用下面的upsert来做到这一点。

whoUseIt功能中使用此upsert。

upsertCollectionMachines()

无论是插入还是更新,它始终会设置InfosMachines.upsert({ nameMachine: machineInfo.name, }, { $set: { stateMachine: machineInfo.state, ipAddr: machineInfo.driver.ipAddress, port: port, protocol: protocol }, $setOnInsert: { isUsed: false, whoUseIt: "", } }); stateMachineipAddrport字段,但只会修改protocol和{ {1}}如果它正在插入(因此,它不会覆盖从另一个函数设置的值)。

isUsed功能中使用此upsert。

whoUseIt

它只会插入或更新这两个特定字段(lockTheMachine()InfosMachines.upsert({ nameMachine: nameMachine, }, { $set: { isUsed: true, whoUseIt: nameUser } }); )。

现在,为什么这样做?首先,我们使用update operator expressions(而不仅仅是isUsed个表达式),它们只允许您在需要时更新特定字段,并且使用whoUseIt确保我们只在插入时修改这些字段。请注意,如果upsert确定需要插入新文档,则根据mongodb upsert option behavior,它会使用...创建一个新文档。

  

如果field:value参数包含更新运算符表达式,则$setOnInsert<query>参数的字段和值

这意味着您无需在更新表达式中明确<update> <update> $set字段。