У Pymongo есть несколько помощников по качеству жизни для класса Cursor
, поэтому он автоматически сделает за вас пакет и вернет вам результат с точки зрения документов.
Параметр batch_size
установлен, но идея в том, что вам нужно только установить его в методе find()
, а не выполнять ручные низкоуровневые вызовы или перебирать партии.
Например, если у меня 100 документов вмоя коллекция:
> db.test.count()
100
Затем я задаю уровень профилирования , чтобы регистрировать все запросы:
> db.setProfilingLevel(0,-1)
{
"was": 0,
"slowms": 100,
"sampleRate": 1,
"ok": 1,
...
Затем я использую pymongo, чтобы указать batch_size
из 10:
import pymongo
import bson
conn = pymongo.MongoClient()
cur = conn.test.test.find({}, {'txt':0}, batch_size=10)
print(list(cur))
Запустив этот запрос, я вижу в журнале MongoDB:
2019-02-22T15:03:54.522+1100 I COMMAND [conn702] command test.test command: find { find: "test", filter: {} ....
2019-02-22T15:03:54.523+1100 I COMMAND [conn702] command test.test command: getMore { getMore: 266777378048, collection: "test", batchSize: 10, ....
(getMore repeated 9 more times)
Таким образом, запрос был получен с сервера в указанных пакетах.Это просто скрыто от вас через Cursor
класс.
Редактировать
Если вам действительно нужно получить документы в пакетном режиме, естьфункция find_raw_batches()
в разделе Коллекция ( ссылка на документ ).Этот метод работает аналогично find()
и принимает те же параметры.Однако имейте в виду, что он вернет сырой BSON, который необходимо будет декодировать приложением на отдельном этапе.Примечательно, что этот метод не поддерживает сеансов .
Сказав, что, если целью является снижение использования памяти приложением, стоит рассмотреть возможность изменения запроса, чтобы вместо него использовались диапазоны.Например:
find({'$gte': <some criteria>, '$lte': <some other criteria>})
Запросы диапазона легче оптимизировать, могут использовать индексы и (на мой взгляд) легче отлаживать и легче перезапускать, если запрос прерывается.Это менее гибко при использовании пакетов, когда вам нужно перезапустить запрос с нуля и снова просмотреть все пакеты, если он будет прерван.