Я использую Node.js
, mongoose.js
и mongoDB
на уровне M0 Sandbox (General)
атласа. Я хочу использовать потоковую передачу для лучшей оптимизации использования ресурсов. вот мой код:
let counter = 0;
let batchCounter = 0;
const batchSize = 500;
const tagFollowToBeSaved = [];
let startTime;
USER.find({}, { _id: 1 }).cursor()
.on('data', (id) => {
if (counter === 0) {
startTime = process.hrtime();
}
if (counter === batchSize) {
counter = 0;
const [s2] = process.hrtime();
console.log('finding ', batchSize, ' data took: ', s2 - startTime[0]);
TAG_FOLLOW.insertMany(tagFollowToBeSaved, { ordered: false })
.then((ok) => {
batchCounter += 1;
const [s3] = process.hrtime();
console.log(`batch ${batchCounter} took: ${s3 - s2}`);
})
.catch((error) => {
console.log('error in inserting following: ', error);
});
// deleting array
tagFollowToBeSaved.splice(0, tagFollowToBeSaved.length);
}
else {
counter += 1;
tagFollowToBeSaved.push({
tagId: ObjectId('5e81ba5a5c86d7215cdc9c88'),
followedBy: id,
});
}
})
.on('error', (error) => {
console.log('error while streaming: ', error);
})
.on('end', () => {
console.log('END');
});
Что я делаю:
- сначала я читаю
_id
с из USER
коллекции 200k пользователей, использующих API потоков с cursor
- проверяет, достигло ли число операций чтения
_id
s предельного размера пакета, если да, я собираюсь вставить эти данные в TAG_FOLLOW
модель.
Все console.log
предназначены для анализа, и вы можете их игнорировать.
Однако insertMany
не работает должным образом. Поскольку я отслеживаю базу данных при вставке данных, Кажется, что она вставляет около 100 данных вместо 500 на размер пакета без каких-либо ошибок , поэтому я теряю 400 данных на пакет, что так недопустимо!
Хотя я изменил значение batchSize
, оно все равно не работает, и я собираюсь потерять некоторые данные в пакете.
Так в чем проблема? Каков наилучший подход для сохранения большого объема данных оптимизированным и надежным способом?
Заранее спасибо.