Nodejs mongoose 如何一次性更新大量文档?

发布于 1周前 作者 eggper 来自 nodejs/Nestjs

Nodejs mongoose 如何一次性更新大量文档?

在做 node 爬虫。

目前用的是 BulkWrite :

const Book = mongoose.model('Book', bookSchema);
exports.saveAll = (from_en, books) => {
    const bulkWrite = books.map(book => ({
        replaceOne: {
            filter: {
                from_en,
                originId: book.originId
            },
            replacement: book,
            upsert: true
        }
    }))
    return Book.bulkWrite(bulkWrite).catch(error => console.error(error))
}

然后发现,这么处理 11200 条数据耗时 600s:

catId: 82 from 5040 to 5600. crawl cost: 10.1min, dataTotal: 11200, upsertTotal: 11000, matchTotal: 200
mongodb is disonnected
mongodb: 603757.883ms
✨  Done in 604.47s.

这个该如何优化?

下面是部分爬虫逻辑的代码: while 内部的代码

机子性能:I7 6700HQ / 16G RAM


4 回复

额,必须充钱才能置顶吗?



不顺序执行的话,如何知道执行完成?

在Node.js中使用Mongoose一次性更新大量文档,可以通过多种方式实现,但需要注意性能和内存使用。以下是两种常用的方法:

方法一:使用Model.updateMany()

updateMany()方法适用于需要更新多个文档且每个文档更新的字段相同的情况。

const mongoose = require('mongoose');
const { Schema } = mongoose;

const MyModel = mongoose.model('MyModel', new Schema({
  field: String,
}));

async function updateDocuments() {
  await mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });
  
  try {
    await MyModel.updateMany(
      { /* 查询条件 */ },
      { $set: { field: 'newValue' } }
    );
  } catch (err) {
    console.error(err);
  } finally {
    await mongoose.disconnect();
  }
}

updateDocuments();

方法二:使用批量操作(Bulk Write)

如果需要为每个文档设置不同的值,可以使用批量操作。

async function bulkUpdateDocuments() {
  const bulkOps = [];
  
  // 构建批量操作数组
  for (let i = 0; i < 1000; i++) {
    bulkOps.push({
      updateOne: {
        filter: { _id: mongoose.Types.ObjectId(`...${i}...`) }, // 根据实际情况替换
        update: { $set: { field: `value${i}` } }
      }
    });
  }

  try {
    await MyModel.bulkWrite(bulkOps);
  } catch (err) {
    console.error(err);
  }
}

bulkUpdateDocuments();

选择哪种方法取决于具体需求,如果更新内容相同,使用updateMany更高效;如果更新内容不同,则使用批量操作。

回到顶部