узел с mongodb: итерация по отдельному результату, не загружая все в память - PullRequest
1 голос
/ 06 мая 2020

Я обнаруживаю узел и пн go одновременно, и у меня был один вопрос:

У меня есть коллекция City:

{
  _id : mongoid
  countryId : string
  name : string
}

Каждый город привязан к одной стране , и несколько городов могут быть присоединены к одной стране. По внешней причине эти данные были повреждены, и некоторые города имеют имя, равное нулю, а не действительное значение (например, Париж или Лондон). Мне нужно удалить все города (с допустимым именем или пустым именем) для страны, в которой хотя бы один город имеет имя, равное нулю.

Например:

  1. если в стране Франция всего 2 города (один с названием Париж, а другой с именем Марсель), ничего не нужно удалять
  2. , если в стране Франция только 2 города (один с названием Париж, а другой с нулевым именем), оба города должны быть удалены
  3. если в стране Франция есть только 2 города (оба с пустыми названиями), оба города должны быть удалены

Мне удалось сделать это с помощью следующего code (node-mongodb-native 3.1 и node 12.16.1):

const invalidCountryIds = await db.collection('City').distinct('countryId',
{
  name:null
}

console.log(invalidCountryIds.length)

invalidCountryIds.forEach(async countryId => {
    await db.collection('City').deleteMany({
        countryId:countryId
    })

Однако у меня есть 2 вопроса, эта коллекция City может быть очень большой (более 10k записей) поэтому я хотел быть уверен, что делаю это наиболее эффективным способом:

  1. когда я вызываю .length, загружаю ли я всю коллекцию invalidCountryIds в память
  2. это foreach лучший способ итерации на th является набором invalidCountryIds, я вижу в документации, что я также могу использовать метод .next, доступный из объекта курсора, есть ли разница между итерацией с этим foreach и next cursor, оба загружаются в память только текущий элемент коллекции?

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

1 Ответ

0 голосов
/ 06 мая 2020
  1. Вы уже загрузили весь результат invalidCountryIds, когда вы запрашиваете его с помощью await db.collection('City').distinct('countryId', { name: null })
  2. Используя cursor, вы загружаете результат в память построчно (по умолчанию ), и вы можете обрабатывать каждую строку. Таким образом, использование cursor будет более эффективным с точки зрения памяти (не обязательно быстрее). В запросах, отличных от distinct, вы также можете указать batchSize, количество документов, которые вы будете извлекать из базы данных для каждой партии.
...