Невозможно вернуть последние документы из MongoDB

Я новичок в MongoDB, но у меня, похоже, есть тривиальная проблема с Mongolab, который я использую от Heroku.

Если я вставлю новый документ, у меня не будет ошибок. Но MongoDB Mongolab, похоже, не возвращает никаких документов после определенного документа. Также не последний документ, который я вставляю.

Вот пример; Я вставляю новый документ и запрашиваю последний. Должно быть так же, верно. Но это не так.

rs-ds027491:PRIMARY> db.measurements.insert({"temperature":"24.687","timestamp":"Sat, 24 Jan 2015 16:00:02 -0000","epoch_timestamp":1422108002})

WriteResult({ "nInserted" : 1 })

rs-ds027491:PRIMARY> db.measurements.find().limit(1).sort({$natural:-1})

{ "_id" : ObjectId("54c37fe687db950c001d04f4"), "temperature" : "24.75", "timestamp" : "Sat, 24 Jan 2015 13:20:02 -0000", "epoch_timestamp" : 1422098402 }

Я также попытался перебрать все документы (как из командной строки, так и с помощью Robomongo. Я получаю одинаковый результат в обоих):

db.measurements.find({})
... after some 'it's...
{ "_id" : ObjectId("54c37eba87db950c001d04f3"), "temperature" : "24.75", "timestamp" : "Sat, 24 Jan 2015 13:15:02 -0000", "epoch_timestamp" : 1422098102 }
{ "_id" : ObjectId("54c37fe687db950c001d04f4"), "temperature" : "24.75", "timestamp" : "Sat, 24 Jan 2015 13:20:02 -0000", "epoch_timestamp" : 1422098402 }

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

Есть ли что-то в Mongo или Mongolab, чего я не понимаю, или это должно сработать, но по какой-то причине это не так?


person Johan Paul    schedule 25.01.2015    source источник


Ответы (2)


Хотя с новой небольшой коллекцией может показаться иначе, естественный порядок отличается от порядка вставки. Естественный порядок возвращает документы в том порядке, в котором они упоминаются во внутренних структурах данных коллекции, что оптимизировано для производительности, а не для отслеживания времени вставки.

http://docs.mongodb.org/manual/reference/operator/meta/natural/

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

person jared    schedule 25.01.2015
comment
Что объясняет его. Ваш подход к отслеживанию времени как индекса также имеет смысл. Спасибо! - person Johan Paul; 25.01.2015

Вы никогда не должны полагаться на естественный порядок, чтобы дать вам последовательный порядок.

Я процитирую документы на это:

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

Вы можете ожидать более последовательного поведения, отсортировав документы по _id (см. ответ Адама о это). Однако даже это может потерпеть неудачу:

Связь между порядком значений ObjectId и временем генерации не является строгой в пределах одной секунды. Если несколько систем или несколько процессов или потоков в одной системе генерируют значения в течение одной секунды; Значения ObjectId не представляют собой строгий порядок вставки. Расхождение часов между клиентами также может привести к нестрогому упорядочиванию даже для значений, поскольку клиентские драйверы генерируют значения ObjectId, а не процесс mongod.

Создание определенного поля для этой цели (например, даты) и его индексация, вероятно, будет лучшим и самым простым подходом.

person joao    schedule 25.01.2015
comment
Я бы пошел с этим, если бы вы в основном показали, как сортировать по _id, который в общем случае должен представлять порядок вставки или, в противном случае, какое-то очень детализированное поле временной метки. Оба актуальны. - person Neil Lunn; 27.01.2015