Reputation: 7622
I have a Mongo collection that has two fields, let's say "name" and "randomString".
I want to create a random string for a name, only if it doesn't exist already. So the first request for { name: "SomeName" }
will result in saving e.g. { name: "someName", randomString: "abc" }
. The second request will do nothing.
Is there a mongo command for this? All I could find are things like findOneAndUpdate
, replaceOne
etc, who all support an optional "upsert" but their behavior on match is to update, I want the behavior on match to be do nothing.
I'm not looking for an if-then solution like in this question, as I have a race condition issue - I need to be able to get multiple requests simultaneously without updating the document or failing any of the requests.
Upvotes: 2
Views: 1396
Reputation: 7622
This is the solution I found in the end:
CustomerRandomString.findOneAndUpdate(
{ name: "someName" },
{
$setOnInsert: { randomString: generateRandomString() },
},
{ upsert: true },
);
The setOnInsert operator only applies when creating a new document, which is exactly what I needed.
EDIT: per the docs, this solution requires a unique index on the field in order to fully avoid duplicates.
Upvotes: 2
Reputation: 619
You can easily do it using the $exists
command to check for randomString
field and then use $set in an aggregation pipeline to upsert that field.
db.collection.updateMany({"name":someName,"randomString":{$exists: false}},[{$set:{"randomString":"abcd"}}],{upsert:true})
If the condition query doesn't match with any documents, then it returns null
.
Note: Aggregation pipeline works in updateMany()
only from MongoDB version 4.2 and above.
Upvotes: 0
Reputation: 198
Yes there is a command for this you can do this by using $addToSet method. For more info please go through the given link: https://docs.mongodb.com/manual/reference/operator/update/addToSet/
PS: If you still have any confusion regarding this question please feel free to comment further.
Thanks
Upvotes: 2