Каков более быстрый способ перебора данных mongo? найти в партии против итерации с курсором?

В моей коллекции mongo более 10 миллионов записей, которые я хочу переместить в другую базу данных.

Есть два способа добиться этого:

Пакетирование данных с помощью find

const batchSize = 1000;
const collection = mongo.client.collection('test');
const count = await quizVersionCollection.count();
let iter = 0;
while (iter * batchSize <= count) {
  const dataArr = await collection.find({})
                  .sort({ _id: -1 })
                  .limit(batchSize)
                  .skip(iter * batchSize)
                  .toArray();
  iter += 1;
}

Использование курсора mongo

while (yield cursor.hasNext()) {
    const ids = [];
    const batchSize = 1000;
    for (let i = 0; i < batchSize; i += 1) {
      if (yield cursor.hasNext()) {
        ids.push((yield cursor.next())._id);
      }
    }
    done += batchSize;
  }

В первом методе я делаю один запрос для каждых 1000 документов, тогда как во втором я делаю 2 запроса для каждого отдельного документа. Какой метод лучше с точки зрения скорости и вычислений?

Может быть, экспорт и импорт тоже будут вариантом? Эта тема производительности обычно зависит от множества факторов. Боюсь, вам нужно будет профилировать его для нескольких записей, чтобы получить содержательный ответ.

dnickless 10.08.2018 14:47

@dnickless Мне нужно проделать некоторые манипуляции и вычисления, потому что я передаю их в Google BigQuery.

Sagar Karira 10.08.2018 14:56
0
2
1 119
1

Ответы 1

Первый метод лучше, потому что, как вы сказали, вы делаете всего 1 вызов на 1000 документов. Таким образом, вы экономите весь сетевой трафик, который будет генерироваться, если вы будете получать документы один за другим. Второй метод потребует много времени в сети, поскольку он извлекает документы один за другим.

Несколько советов:

  1. Никогда не рекомендуется использовать пропуск в запросах mongo, потому что согласно документация mongodb:

    The cursor.skip() method requires the server to scan from the beginning of the input results set before beginning to return results. As the offset increases, cursor.skip() will become slower.

  2. Установите размер пакета чуть менее 16 МБ / (средний размер вашего документа). Это связано с тем, что mongoDB имеет ограничение на размер ответа 16 МБ. Таким образом вы можете свести к минимуму количество звонков, которые вы делаете.

  3. Если вы можете использовать многопоточность, разделите данные на 7 групп, получите ids на границе интервала и используйте эти идентификаторы для создания условий диапазона. Затем вы можете удалить sort, limit и skip. Это сильно повлияет на производительность.

Спасибо, я воспользовался вашим решением, и оно отлично работает!

Alessandro Roaro 18.02.2021 11:33

Другие вопросы по теме