Использование буферизованных данных в режиме сортировки переполнения превышает внутренний предел
Используя код:
all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING)
print all_reviews.count()
print all_reviews[0]
print all_reviews[2000000]
Счетчик печатает 2043484
, и он печатает all_reviews[0]
.
Однако при печати all_reviews[2000000]
я получаю сообщение об ошибке:
pymongo.errors.OperationFailure: ошибка базы данных: ошибка Runner: переполнение буфера с использованием переполнения данных с использованием 33554495 байтов превышает внутренний предел 33554432 байт
Как мне это сделать?
Ответы
Ответ 1
Вы используете ограничение 32 МБ для сортировки в памяти:
https://docs.mongodb.com/manual/reference/limits/#Sort-Operations
Добавьте индекс в поле сортировки. Это позволяет MongoDB передавать вам документы в отсортированном порядке, а не пытаться загрузить их все в память на сервере и сортировать их в памяти перед отправкой их клиенту.
Ответ 2
Как сказано в разделе kumar_harsh
в разделе комментариев, я хотел бы добавить еще одну точку.
Вы можете просмотреть текущее использование буфера, используя следующую команду в базе admin
:
> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }
Он имеет значение по умолчанию 32 МБ (33554432 байта). В этом случае у вас недостаточно данных буфера, поэтому вы можете увеличить ограничение буфера с помощью своего собственного оптимального значения, например, 50 МБ как показано ниже:
> db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }
Надеюсь, это поможет!!!
Note
: Эти команды поддерживаются только после версии 3.0 +
Ответ 3
решена с индексированием
db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
Ответ 4
Если вы хотите избежать создания индекса (например, просто хотите быстро и грязную проверку для изучения данных), вы можете использовать агрегацию с использованием диска:
all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})
(Не уверен, как это сделать в пимонго, хотя).
Ответ 5
В моем случае необходимо было исправить индексы nessary в коде и заново создать их:
rake db:mongoid:create_indexes RAILS_ENV=production
Поскольку переполнение памяти не происходит, когда есть необходимый индекс поля.
PS До этого мне пришлось отключать ошибки при создании длинных индексов:
# mongo
MongoDB shell version: 2.6.12
connecting to: test
> db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )