Reputation: 1192
Hi, I don't know how to put a good title for it but I'm sure you will understand
So I'm trying to set 2 fields on my Mongo collection when the user click on a button BUT every 60sc I have a method that is running and who make that:
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();
}
}
}));
})
Where the important part is the InfosMachines.upsert()
. Now I want to set 2 fields like this :
'lockTheMachine': function(nameMachine, nameUser){
InfosMachines.upsert({
nameMachine: nameMachine,
}, {
nameMachine: nameMachine,
isUsed: true,
whoUseIt: nameUser
});
//upsertCollectionMachines();
console.log(nameUser +" has locked the machine: " + nameMachine);
},
But first it doesn't look likes it add the 2fields to the collection and secondly the 60s interval method will delete them right ?
Thank you for the help
Upvotes: 0
Views: 31
Reputation: 10705
It was a little hard to follow exactly what you are trying to do in your question, but I think I got the main gist of it.
Basically, you want the lockTheMachine()
function upsert to only ever set nameMachine
, isUsed
, and whoUseIt
fields and you only want upsertCollectionMachines()
to set stateMachine
, ipAddr
, port
, protocol
fields on update and only set isUsed
and whoUseIt
to default values on insert?
You should be able to do that using the below upserts.
Use this upsert inside your upsertCollectionMachines()
function.
InfosMachines.upsert({
nameMachine: machineInfo.name,
}, {
$set: {
stateMachine: machineInfo.state,
ipAddr: machineInfo.driver.ipAddress,
port: port,
protocol: protocol
},
$setOnInsert: {
isUsed: false,
whoUseIt: "",
}
});
It will always set stateMachine
, ipAddr
, port
, protocol
fields regardless if it is inserting or updated, but will only modify isUsed
and whoUseIt
if it is inserting (therefore, it will not overwrite the values set from the other function).
Use this upsert inside your lockTheMachine()
function.
InfosMachines.upsert({
nameMachine: nameMachine,
}, {
$set: {
isUsed: true,
whoUseIt: nameUser
}
});
It will only ever insert or update those 2 specific fields (isUsed
and whoUseIt
).
Now, why does this work? First, we are using update operator expressions (instead of only field:value
expressions) which allow you to only update specific fields when needed and using $setOnInsert
ensures that we only ever modify those fields on insert only. Note, that if the upsert determines it needs to insert a new document, per the mongodb upsert option behavior, it creates a new document using...
The fields and values of both the
<query>
and<update>
parameters if the<update>
parameter contains update operator expressions
This means you don't have to ever actually $set
the nameMachine
field explicitly in the update expression.
Upvotes: 1