How to perform Bulk Upsert

Hi!

I’m trying to perform a Bulk Upsert for documents. I understand this can’t be done natively in Meteor:Mongo and that the Node MongoDB lib has to be used with rawCollection instead.

I have the following

const bulkUpserts = [];
for (let doc of docs) {

  bulkUpserts.push({
                 updateOne: {
                     filter: {
                        fizz: doc.buzz
                     },
                     update: doc,
                     upsert: true,
                     setOnInsert: {
                         "foo": "bar",
                         "createdBy": Meteor.userId(),
                         "createdDate": new Date()
                     }
                 }
             });
}

Collection.rawCollection().bulkWrite(bulkUpserts);

The issue with ^ is that the setOnInsert doesn’t seem to work. My foos aren’t being set. Looks like setOnInsert isn’t available as an option for updateOne. What’s the alternative though? I surprisingly cannot find a way to do this in Meteor yet.

Thanks!

$setOnInsert is an update operator that you would have to use within the update parameter (see here). This can either be a document or a pipeline, see https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#bulkwrite-write-operations-updateonemany

In your case it is a document, so in this way you can’t possibly use $setOnInsert.

Do you personally use regular update (as opposed to updateOne) in tandem with bulkWrite to achieve your, “bulkUpserts” then?

My previous way of using straight Meter Mongo Collection upsert in a for loop did not scale

I’m now trying

` bulk.find({
fizz: doc.buzz
}).upsert().updateOne({
$set: doc,
$setOnInsert: {
_id: Random.id(),
“foo”: “bar”,
“createdBy”: Meteor.userId(),
“createdDate”: new Date()
}
});

This seems to work. Any thoughts on this vs bulkWrite? How do you personally perform “bulk upserts”? Ideally, I’d prefer to keep using meteor:mongo.upsert. If only, I could do that as a bulk Op though