0

Мне было интересно Spring Mongo API для find загружает все в List. Если результат поиска содержит миллиард записей, не повлияет ли это на память? Может ли кто-то предложить лучший способ достичь этого, не загружая все это в память. Использование лимита может помочь, но тогда есть недостаток, что он не знает, вставлен ли новый документ в коллекцию. Ну, find by limit будет иметь тот же эффект, если коллекция изменит после чтения X of billion записей.Захват неизвестного документа, добавленного во время большого поиска в Mongodb

Так два вопроса:

  • Повышение производительности не загружая все в памяти
  • Как бы вы решить эту не-известный документ добавлен в процессе обработки?

код из API

List<T> result = new ArrayList<T>(); 

while (cursor.hasNext()) { 
    DBObject object = cursor.next(); 
    result.add(objectCallback.doWith(object)); 
} 

ответ

1

Повышение производительности не загружая все в памяти

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

В MongoDB сервер возвращает результаты запроса в cursor batches, что не может превышать 16 МБ (maximum BSON document size как у MongoDB 3.0 .. и на самом деле обычно 1 МБ для первой партии и 4 МБ для последующих партий). Вы можете создать больший результат, продолжая перебирать курсор в коде приложения, но реализация - ваш выбор.

Как бы вы разрешили этот неопубликованный документ, добавленный во время обработки?

Закажите ваши результаты поиска по свойствам новых документов, которые монотонно увеличиваются - например, по умолчанию ObjectId. Курсоры (как в MongoDB 3.0) не обеспечивают изоляцию от активности записи, поэтому документы, которые вставлены или обновлены во время обработки, также будут включены, если они применимы к порядку запроса.

Если ваш код выполняет итерацию большого запроса, отсортированного по _id (по возрастанию), новые документы, вставленные с использованием ObjectId по умолчанию, должны появляться в последних партиях.

+0

Это реальный прецедент. В Expedia (ваш клиент) наша группа также является держателем данных. Любая группа может запросить все данные с начала времени от нас. Мы поощряем сбор данных каждый месяц, но может быть случай, когда группа просто хотела бы начать новую работу. Эти группы проводят анализ исторических данных. Таким образом, как он был решен, используется предел вместимостью 100 000 записей. –

+0

Которое я считаю потоковым 7-10 миллионов записей в течение 25 минут между двумя разными центрами обработки данных в двух разных местах. Таким образом, теперь возникает вопрос о том, как получить новый документ или обновленный документ, который произошел между 25 минутами. Я могу получить новые данные по типу '_id', но как насчет обновлений? Должен ли я включать сортировку по 'update'? –

+0

@java_dude Только ваш оригинальный вопрос об обнаружении новых документов, вставленных при повторении большого запроса; обновления должны обрабатываться по-разному. Вы можете использовать значение часового с меткой времени (например.последняя измененная дата в документах) или настроить процесс, чтобы привязать oplog (ы) к модифицированным документам на основе пространства имен и фильтра запросов. В зависимости от вашей модели данных могут быть более эффективные варианты, но это более продолжительное обсуждение, чем работа в комментариях здесь :). – Stennie