MongoDB - Get IDs of inserted and existing documents after “Insert if not exist” operation on multiple documents

爱⌒轻易说出口 提交于 2021-01-05 11:24:08

问题


I have to insert multiple documents if they don't already exist, but the important thing is that in the query results I need to have IDs of both the inserted and already existing items.

I'm trying with the following bulkWrite operation:

// external_id is a unique id other than the mongo _id
let items = [
   {external_id: 123, name: "John"},
   {external_id: 456, name: "Mike"},
   {external_id: 789, name: "Joseph"}
];
db.collection("my_collection")
  .bulkWrite(
    items.map((item) => {
      return {
        updateOne: {
          filter: { external_id: item.external_id },
          update: { $setOnInsert: item},
          upsert: true,
        },
      };
    })
  );

The problem is that the BulkWriteResult return only the _id of the inserted items in upsertedIds, while for the existing items return only the nMatched number.

The other solution I have think about is to make (1) a find over an array of ids, (2) check the results for the ones already existing, and (3) then insertMany for the new ones:

 let ids = [123, 456, 789];
 let items = [
   {external_id: 123, name: "John"},
   {external_id: 456, name: "Mike"},
   {external_id: 789, name: "Joseph"}
 ];

 // STEP 1: Find alredy existings items
 db.collection("my_collection")
  .find({ external_id: { $in: ids } })
  .toArray(function (err, existingItems) {
     // If John already exist
     // existingItems = [{_id: ObjectId, external_id: 123, name: "John"}]

     // STEP 2: Check which item has to be created
     let itemsToBeCreated = items.filter((item) =>
       !existingItems.some((ex) => ex.external_id === item.external_id)
     );

     // STEP 3: Insert new items
     db.collection("my_collection")     
       .insertMany(itemsToBeCreated, function (err, result) {          
         // FINALLY HERE I GET ALL THE IDs OF THE EXISTING AND INSERTED ITEMS
     });
  });

With this solution I'm concerned about performance, because these operations are fired 100K times a day for 10 items each, and about 90% of the times the items are new. So 900K new items and 100K already existing.

I would like to know if there is a better way of achieving this.

Thanks in advance

来源:https://stackoverflow.com/questions/65342270/mongodb-get-ids-of-inserted-and-existing-documents-after-insert-if-not-exist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!