Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB bulk operator, insert if not exists

Tags:

mongodb

I'm using the MongoDB bulk operation to insert documents.

What I'd like to do is insert, only if no document is found - I don't want to update if it is found (i.e., upsert).

Any ideas how to do this?

However, even in this case:

var obj = {
 item: 'test'
}

bulk.find({ item: {$ne : obj.item}}).upsert().updateOne(obj);
bulk.execute();

This doesn't seem to actually insert anything if not found.

EDIT:

I wanted to update this to clarify a bit more.

There are two operations I'm trying to perform, using bulk api, one is to update and one is to insert.

The document looks like this:

{
  item: 'test',
  categories: [{
     name: 'one',
     attr: 'two'
  }]
}

What I'd like to do is if the item value is not found, then insert the obj. However, if it is found, then if categories.name is not found, $push the category object to the categories array. If the document is found and the category exists, do nothing.

like image 954
dzm Avatar asked Aug 05 '16 23:08

dzm


People also ask

Does MongoDB update insert if not exists?

You can use upsert i.e. whenever you insert a value and it already exist then update would be performed. If the value does not already exist then it would get inserted.

What is bulk insert in MongoDB?

Multiple documents can be inserted at a time in MongoDB using bulk insert operation where an array of documents is passed to the insert method as parameter.

What is bulkWrite?

By default, bulkWrite() performs ordered operations. To specify unordered write operations, set ordered : false in the options document. See Execution of Operations.

What is $Set in MongoDB?

$set outputs documents that contain all existing fields from the input documents and newly added fields. The $set stage is an alias for $addFields. Both stages are equivalent to a $project stage that explicitly specifies all existing fields in the input documents and adds the new fields.


1 Answers

What you'd want is to maintain the same update operation but change the query. From the documentation:

Bulk.find(<query>).upsert().update(<update>); Bulk.find(<query>).upsert().updateOne(<update>); Bulk.find(<query>).upsert().replaceOne(<replacement>);

With the upsert option set to true, if no matching documents exist for the Bulk.find() condition, then the update or the replacement operation performs an insert. If a matching document does exist, then the update or replacement operation performs the specified update or replacement.

Change the query to look for documents that satisfy the condition:

var obj = { item: 'test' };

bulk.find(obj).upsert().updateOne({ $setOnInsert: obj });
bulk.execute();

In the above, if the a matching document does exist, then the update with $setOnInsert does nothing as the update operation does not result in an insert, having found a document that matches the query.

like image 79
chridam Avatar answered Oct 12 '22 18:10

chridam