首页 > 解决方案 > MongoDB - 在对多个文档进行“如果不存在则插入”操作后获取插入和现有文档的 ID

问题描述

如果它们尚不存在,我必须插入多个文档,但重要的是,在查询结果中,我需要同时拥有已插入和已存在项目的 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,
        },
      };
    })
  );

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

我考虑的另一个解决方案是(1)find在一个id数组上创建一个,(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
     });
  });

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

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

提前致谢

标签: mongodbmongodb-query

解决方案


推荐阅读