mongodb insert multiple documents if they don't exist otherwise do nothing

Viewed 286

I want to store tags that users input freeform so I can offer them as suggestions when other users input tags.

How can I insert all the new tags a user has input only where the tag doesn't already exist in my suggestions collection?

For example I have an array like this of tags that a user input:

[
   {"name": "tag 1"}, 
   {"name": "tag 2"}, 
   {"name": "tag 3"},
   {"name": "tag 4"},
   {"name": "tag 5"}
]

And the collection I'm inserting to has these documents already.

{ _id: <IDHERE>, "name": "tag 2" }
{ _id: <IDHERE>, "name": "tag 4" }
{ _id: <IDHERE>, "name": "tag 5" }

I want to end up with the collection having all these records like this:

{ _id: <IDHERE>, "name": "tag 1" }
{ _id: <IDHERE>, "name": "tag 2" }
{ _id: <IDHERE>, "name": "tag 3" }
{ _id: <IDHERE>, "name": "tag 4" }
{ _id: <IDHERE>, "name": "tag 5" }

Is there a way with a single statement to pass the array above to that collection and have it insert {"name": "tag 1"} and {"name": "tag 3"} and ignore the others since they already exist.?

1 Answers

I am not sure it is possible with single query, you can try upsert in update command, example in js/nodejs,

  • iterate loop of tags array and update query by checking name and set name,
let tags = [{"name": "tag 1"}, {"name": "tag 2"}, {"name": "tag 3"}, {"name": "tag 4"}, {"name": "tag 5"}];

tags.forEach(function(tag) {
  db.collection.updateOne(
    { name: tag.name }, 
    { $set: { name: tag.name } },
    { upsert: true }
  )
});

Playground


You can use bulkWrite() method,

let bulkTags = [];

tags.forEach(function(tag) {
  bulkTags.push({
    updateOne: {
      filter: { name: tag.name },
      update: { $set: { name: tag.name } },
      upsert: true
    }
  });
});

db.collection.bulkWrite(bulkTags);
Related