简体   繁体   中英

Mongo: create if document doesn't exist, otherwise do nothing

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 eg { 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.

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM