Вопрос или проблема
Я разрабатываю приложение на Node.js, которое требует добавления расписаний событий в базу данных MongoDB. В настоящее время моя реализация использует вложенные циклы для создания этих записей о событиях, что может привести к проблемам с производительностью при обработке больших наборов данных.
Здесь я хочу пропустить часть итерации из этого кода. Как вы можете увидеть, этот код может привести нас к неопределенному количеству итераций, что может замедлить этот процесс. Есть ли способ, при котором мы можем ограничить или убрать эту часть итерации?
exports.addEventSchedules = async (req) => {
const {
eventIdentifier,
startTime,
endTime,
isSameDayFlag,
selectedDaysArray,
} = req.body;
const eventScheduleArray = [
{
eventStartDate: "2024-02-29T18:30:00.000Z",
eventEndDate: "2024-03-01T18:30:00.000Z",
eventStartDay: "Friday",
eventEndDay: "Saturday",
},
{
eventStartDate: "2024-03-03T18:30:00.000Z",
eventEndDate: "2024-03-04T18:30:00.000Z",
eventStartDay: "Monday",
eventEndDay: "Tuesday",
},
{
eventStartDate: "2024-03-07T18:30:00.000Z",
eventEndDate: "2024-03-08T18:30:00.000Z",
eventStartDay: "Friday",
eventEndDay: "Saturday",
},
];
const eventDataList = await fetchEventsByIdentifier({
eventIdentifier,
});
const eventScheduleDocuments = eventDataList.flatMap(
(eventData) => {
const eventID = eventData.id;
const eventSegmentID = eventData.segmentId;
return eventScheduleArray.map((eventScheduleEntry) => ({
eventId: eventID,
segmentId: eventSegmentID,
eventStartDate: eventScheduleEntry.eventStartDate,
eventEndDate: eventScheduleEntry.eventEndDate,
eventStartDay: eventScheduleEntry.eventStartDay,
eventEndDay: eventScheduleEntry.eventEndDay,
}));
},
);
return insertEventSchedules(eventScheduleDocuments);
};
Текущий подход использует вложенные циклы для создания записей о расписании событий. Это может быть неэффективно, особенно при обработке большого количества событий и дат. Я ищу способ оптимизировать этот процесс, особенно используя операции пакетной записи MongoDB для уменьшения числа отдельных вставок.
Вопрос
- Как я могу рефакторить этот код, чтобы эффективно использовать операции пакетной записи MongoDB?
- Какой лучший способ избежать вложенных циклов, при этом гарантируя, что все записи расписания событий будут созданы и сохранены правильно?
- Есть ли какие-либо лучшие практики для структурирования данных для пакетных вставок в MongoDB, которые я должен учитывать?
Я просто не хочу использовать цикл, и мои данные будут выглядеть так:
{
EventId: eventId
“eventStartDate”: “2024-03-07T18:30:00.000Z”,
“eventEndDate”: “2024-03-08T18:30:00.000Z”,
“eventStartDay”: “Friday”,
“eventEndDay”: “Saturday”
}
Ответ или решение
Для оптимизации массовой вставки расписаний событий в базе данных MongoDB без использования вложенных циклов, мы можем использовать механизм пакетной записи, который значительно увеличит производительность, особенно при обработке больших объемов данных. Рассмотрим, как это можно реализовать.
Оптимизация массовой вставки с использованием MongoDB Bulk Write
-
Переписывание функции
addEventSchedules
:Избавляемся от вложенных циклов, применяя метод
map
для создания массива документов, который затем передается в команду массовой записи.
exports.addEventSchedules = async (req) => {
const {
eventIdentifier,
startTime,
endTime,
isSameDayFlag,
selectedDaysArray,
} = req.body;
const eventScheduleArray = [
{
eventStartDate: "2024-02-29T18:30:00.000Z",
eventEndDate: "2024-03-01T18:30:00.000Z",
eventStartDay: "Friday",
eventEndDay: "Saturday",
},
{
eventStartDate: "2024-03-03T18:30:00.000Z",
eventEndDate: "2024-03-04T18:30:00.000Z",
eventStartDay: "Monday",
eventEndDay: "Tuesday",
},
{
eventStartDate: "2024-03-07T18:30:00.000Z",
eventEndDate: "2024-03-08T18:30:00.000Z",
eventStartDay: "Friday",
eventEndDay: "Saturday",
},
];
// Получите данные событий по идентификатору
const eventDataList = await fetchEventsByIdentifier({ eventIdentifier });
// Создание массива для массовой записи.
const bulkOps = eventDataList.reduce((acc, eventData) => {
const eventID = eventData.id;
const eventSegmentID = eventData.segmentId;
// Собираем операции массовой записи для каждого расписания
const operations = eventScheduleArray.map(eventScheduleEntry => ({
insertOne: {
document: {
eventId: eventID,
segmentId: eventSegmentID,
eventStartDate: eventScheduleEntry.eventStartDate,
eventEndDate: eventScheduleEntry.eventEndDate,
eventStartDay: eventScheduleEntry.eventStartDay,
eventEndDay: eventScheduleEntry.eventEndDay,
},
},
}));
return acc.concat(operations);
}, []);
// Выполните массовую запись в базу данных
if (bulkOps.length) {
await insertEventSchedules(bulkOps);
}
};
-
Избежание вложенных циклов:
Мы используем метод
reduce
для создания массива операций, который связывает дата события и его идентификатор с массивом расписаний. Это устраняет необходимость использования вложенных циклов. -
Массовая запись с использованием
insertMany
:Вместо передачи документов по одному, мы передаем массив под единой командой, используя команду
insertMany
, что значительно ускоряет процесс.
Рекомендации по структурированию данных для пакетных вставок
-
Используйте правильные индексы:
Убедитесь, что вы создали индексы на полях, которые будете часто использовать в запросах. Это поможет улучшить производительность запросов к коллекции. -
Компактные документы:
Старайтесь, чтобы документы были компактными. Уменьшение размера документов помогает ускорить операции записи и чтения. -
Убедитесь в целостности данных:
Перед выполнением массовых операций валидация данных может помочь избежать обработки неверных записей.
Эта структура позволяет отправлять всего один запрос на вставку, а не множество отдельных, что сэкономит время обработки на стороне сервера и уменьшит нагрузку на сеть, обеспечивая более эффективную работу вашего приложения.