I have a collection which looks like this (fields removed for brevity):
[
{ "id": "A", "name": "AA" ,"arrayField": [1, 2, 3] },
{ "id": "B", "name": "BB" ,"arrayField": [4, 5, 6] },
{ "id": "C", "name": "CC" ,"arrayField": [7, 8] }
]
Consider each object as a document.
Now in my application, after some business logic, I have an array of POJOs which look like this:
[
{ "id": "A", "name": "AB", "arrayField": [1, 2, 3] },
{ "id": "B", "name": "VB", "arrayField": [4, 5, 6] },
{ "id": "C", "name": "DE", "arrayField": [7, 8] }
{ "id": "D", "name": "GG", "arrayField": [10, 11] }
]
Note that these objects don't have the other fields required by the document.
arrayField and the name fields of documents with id A, B** and C to reflect the array of objects.id D which have to be inserted in the collection (the other fields will be taken care of as they have default values in the schema).Note: arr is the array of objects being talked about.
updateMany with upsert:
Model.updateMany({ id: { $in: arr.map(({ id }) => id) } }, arr, { upsert: true });
Mapping over the array of objects and updating with upsert:
await Promise.all(
arr.map(({ id, arrayField, name }) => {
return Model.updateOne({ id }, { $set: { arrayField, name } }, { upsert: true });
})
);
Is there any way to do this using transactions/aggregations/etc.?
As @ray suggested in the comments, I was looking for bulk operations. I did something along the lines of:
const bulk = Model.initializeUnorderdBulkOp();
arr.forEach(({ id, arrayField, name }) => {
bulk.find({ id }).upsert().updateOne({ $set: { arrayField, name } });
});
bulk.execute();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With