Ответ 1
Попробуйте добавить индекс {community_id: 1, 'updated_at.t': -1}
. Сначала нужно выполнить поиск по community_id
, а затем отсортировать.
Я использую MongoDB 1.6.3, чтобы хранить большую коллекцию (300k + records). Я добавил составной индекс.
db['collection_name'].getIndexes()
[
{
"name" : "_id_",
"ns" : "db_name.event_logs",
"key" : {
"_id" : 1
}
},
{
"key" : {
"updated_at.t" : -1,
"community_id" : 1
},
"ns" : "db_name.event_logs",
"background" : true,
"name" : "updated_at.t_-1_community_id_1"
}
]
Однако, когда я пытаюсь запустить этот код:
db['collection_name']
.find({:community_id => 1})
.sort(['updated_at.t', -1])
.skip(@skip)
.limit(@limit)
Я получаю:
Mongo:: OperationFailure (слишком много данных для sort() без индекса. добавить индекс или указать меньший предел)
Что я делаю неправильно?
Попробуйте добавить индекс {community_id: 1, 'updated_at.t': -1}
. Сначала нужно выполнить поиск по community_id
, а затем отсортировать.
Таким образом, он "чувствует", как будто вы используете индекс, но индекс на самом деле является составным индексом. Я не уверен, что сортировка "достаточно умна" для использования только частичного индекса.
Итак, две проблемы:
updated_at.t
звучит как поле, на котором вы будете задавать запросы диапазона. Индексы работают лучше, если запрос диапазона - это второй бит.community_id => 1
? Если число не велико, вы можете избежать просто сортировки без индекса.Поэтому вам может потребоваться переключить индекс, и вам, возможно, придется изменить сортировку, чтобы использовать как community_id
, так и updated_at.t
. Я знаю, что он кажется лишним, но начинайте с него и проверяйте группы Google, если он все еще не работает.
Даже с индексом, я думаю, вы все равно можете получить эту ошибку, если ваш результирующий набор превышает 4 МБ.
Вы можете увидеть размер, перейдя в консоль mongodb и сделав следующее:
show dbs
# pick yours (e.g., production)
use db-production
db.articles.stats
В результате я получил следующие результаты:
{
"ns" : "mdalert-production.encounters",
"count" : 89077,
"size" : 62974416,
"avgObjSize" : 706.9660630690302,
"storageSize" : 85170176,
"numExtents" : 8,
"nindexes" : 6,
"lastExtentSize" : 25819648,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 18808832,
"indexSizes" : {
"_id_" : 3719168,
"patient_num_1" : 3440640,
"msg_timestamp_1" : 2981888,
"practice_id_1" : 2342912,
"patient_id_1" : 3342336,
"msg_timestamp_-1" : 2981888
},
"ok" : 1
}
Наличие слишком большого размера партии курсора вызовет эту ошибку. Установка размера партии не ограничивает объем данных, которые вы можете обрабатывать, а просто ограничивает количество данных, возвращаемых из базы данных. Когда вы перебираете и нажимаете ограничение на пакет, процесс совершит еще одну поездку в базу данных.