Синхронный цикл по большой коллекции MongoDB в Node.js - PullRequest
0 голосов
/ 31 октября 2019

Я знаю, что существуют разные способы просмотра коллекции MongoDB, и многие люди уже задавали этот вопрос на SO. Я проверил многие из них, но не видел ни одного, который бы подходил для большой коллекции.

Мой текущий код выглядит следующим образом:

'use strict'

const mo_mongodb = require('mongodb')

const mongodb = mo_mongodb.MongoClient


const service = (context, out) => {
  const next = context
  next.cursor.current = next.cursor.current + 1

  if (context.cursor.range.minimum + context.cursor.current <= context.cursor.range.maximum) {

    getDocument(context, (status, response) => {
      // 1. making a HTTPS request to a web API
      // 2. saving the returned data to MongoDB
      // 3. recursively calling `service(next)`
    });

  } else {
    context.mongodb.api.close()

    return out('success', { some: 'stats' })
  }
}


const getDocument = (context, next) => {
  context.mongodb.api.db('database_name').collection('collection_name').find().skip(context.cursor.range.minimum + context.cursor.current).limit(1).toArray()
    .then(content => {
      next('success', content)
    })
    .catch(error => {
      next('error', error)
    })
  ;
};



mongodb.connect('mongodb://localhost:12012', { useNewUrlParser: true }, (error, mongo) => {
  if (error) { return console.error(error) }

  service({
    mongodb: {
      api: mongo
    },
    cursor: {
      current: 0,
      range: { minimum: 0, maximum: 189405 }
    }
  }, (status, response) => {
    console.log(response)
  });
});

Сценарий долго работал у меня нормально, однако я заметил, что обработка запроса с большим смещением занимает больше времени. Но это было нормально, пока мне не пришлось обработать довольно большую коллекцию (355 GB - 189405 documents).

Скрипт перестал работать на 63380 documents со следующей ошибкой:

{ MongoNetworkError: connection 1 to localhost:12012 timed out
at Socket.<anonymous> (/storage/steps/03_FIXED-here_locales_on_here_requests/node_modules/mongodb/lib/core/connection/connection.js:335:7)
at Object.onceWrapper (events.js:285:13)
at Socket.emit (events.js:197:13)
at Socket._onTimeout (net.js:447:8)
at listOnTimeout (timers.js:327:15)
at processTimers (timers.js:271:5)
  name: 'MongoNetworkError',
  errorLabels: [ 'TransientTransactionError' ],
  [Symbol(mongoErrorContextSymbol)]: {} }

Я искал эту ошибку и сделал то, что было рекомендовано: увеличено время ожидания соединения

Так что теперь соединение выглядит так:

mongo_server.connect(`mongodb://localhost:12012`, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  socketTimeoutMS: 360000,
  keepAlive: true,
  autoReconnect: true,
  socketTimeoutMS: 360000,
  reconnectTries: 360000,
  poolSize: 30
}, (error, mongo) => { })`

Но после запуска обновленного скрипта - он дает мнета же ошибка.

Как я могу изменить свой петлитель MongoDB для эффективной работы с этими большими коллекциями? Он должен быть синхронным (так как я запрашиваю данные из Интернета) и при желании иметь minimal cursor, чтобы продолжить обработку данных, если сервер по какой-то причине останавливается

Заранее спасибо

...