MongoDB - 在对多个文档执行“如果不存在则插入”操作后获取已插入和现有文档的 ID

fas*_*ros 6 mongodb mongodb-query

如果它们不存在,我必须插入多个文档,但重要的是,在查询结果中,我需要有插入的和已经存在的项目的 ID。

我正在尝试以下bulkWrite操作:

// 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,
        },
      };
    })
  );
Run Code Online (Sandbox Code Playgroud)

问题是BulkWriteResult仅返回_id中插入项目的upsertedIds,而对于现有项目仅返回nMatched数字。

我想到的另一个解决方案是使 (1) 一个findid 数组,(2) 检查已经存在的结果,以及 (3) 然后insertMany检查新的结果:

 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
     });
  });
Run Code Online (Sandbox Code Playgroud)

使用此解决方案时,我担心性能,因为这些操作每天针对 10 个项目触发 100K 次,并且大约 90% 的项目是新的。所以 900K 新项目和 100K 已经存在。

我想知道是否有更好的方法来实现这一目标。

提前致谢