I am trying to create unique passwords for every document in a MongoDB collection. Although the function works, it creates the same password for each user.
Here is the code I am currently using:
function createPasswords(){
db.collection('users').updateMany({}, {$set:{password: GeneratePassword(12, false)}});
}
I expected the GeneratePassword function to be run for each document but it obviously only runs once as the result is the same random password for each user in the collection.
My question is, in this case, how might I create unique passwords for each user at once using updateMany.
Incidentally, the GeneratePassword function is not a custom function but instead calls the password-generator package.
Thanks in advance!
UPDATE
I tried the following code based on the answer by turivishal below.
db.collection('users').updateMany({},[{
$set: { updated: 'true',
password: {
$function: {
body: function() {
$function: {
function passGen(param1, param2) {
return GeneratePassword(param1,param2)
}
return passGen(12, false);
}
},
args: [],
lang: "js"
}
}
}
}]);
This produced the following error:
MongoServerError: Invalid $set :: caused by :: The body function must be specified.
If anyone can spot what is going wrong here I'd much appreciate the guidance.
The update() / updateMany() method in MongoDB is a single write operation, modifies multiple documents, the modification of each document is atomic. (we can not say the whole operation is atomic as per docs), but it will not update the different values in each document of collection.
You have to update it one by one or loop through or you can try an update with aggregation pipeline query starting from MongoDB 4.2, it allows for a more expressive update statement and $function starting from MongoDB 4.4, defines a custom aggregation function or expression in JavaScript.
I would suggest this query only if this is a one-time process because it will impact query speed and performance, and as per operator support, this query will support from MongoDB 4.4 or above versions.
db.collection('users').updateMany(
{},
[{
$set: {
password: {
$function: {
body: function() {
// write your generate password method here
function GeneratePassword(param1, param2) {
// ...
}
// this will call internal method and return password
return GeneratePassword(12, false);
},
args: [],
lang: "js"
}
}
}
}]
)