2017-02-10 3 views
1

Я читал, что Model.collection.insert быстрее, чем Model.create.Mongoose bulk update/save

Я 1kk пользователей в User.collection, я хочу, чтобы обновить их все через каждую 1 минуту: Это мой код:

const mongoose = require('mongoose'); 
const User = require('./models/user'); 
const async = require('async'); 

function getRandomArbitrary(min, max) { 
    return Math.round(Math.random() * (max - min) + min); 
} 

User.find({}, (err, docs) => { 
    async.mapSeries(docs, (doc, callback) => { 
     doc.value = getRandomArbitrary(0,100); 
     doc.save((err) => { 
      callback(err, doc); 
     }); 
    }, (err, result) => { 
     if (err) return err; 
     console.log('completed'); 
    }); 
}); 

Это хороший способ для достижения этой цели? Требуется режим, не превышающий 1 минуту. Как увеличить производительность?

ответ

1

То, как вы делаете это сейчас, - это ожидание сохранения одной вещи перед тем, как перейти к другому. Вы можете распараллелить его (полностью или частично), чтобы сделать его быстрее.

Вы можете использовать async.map вместо async.mapSeries, чтобы заставить его работать параллельно.

Или вы можете использовать async.mapLimit, чтобы ограничить количество операций, совершаемых одновременно.

См:

Пример с async.map:

User.find({}, (err, docs) => { 
    async.map(docs, (doc, callback) => { 
     doc.value = getRandomArbitrary(0,100); 
     doc.save((err) => { 
      callback(err, doc); 
     }); 
    }, (err, result) => { 
     if (err) return err; 
     console.log('completed'); 
    }); 
}); 

Пример с async.mapLimit:

const LIMIT = 10; 
User.find({}, (err, docs) => { 
    async.mapLimit(docs, LIMIT, (doc, callback) => { 
     doc.value = getRandomArbitrary(0,100); 
     doc.save((err) => { 
      callback(err, doc); 
     }); 
    }, (err, result) => { 
     if (err) return err; 
     console.log('completed'); 
    }); 
}); 

Просто LIMIT к тому, что номер, который вы хотите.

+0

async.map - опасная операция, она блокирует цикл события (если вы не создаете отдельный дочерний процесс), и это вызывает утечку памяти. Спасибо, async.mapLimit - лучший вариант – Artur