Reputation: 2456
I am quite new to MongoDB, but I seem to have a trivial problem with Mongolab that I am using from Heroku.
If I insert a new document, I don't get any errors. But Mongolab's MongoDB doesn't seem to return any documents after a certain document. Also not the latest document that I insert.
Here's an example; I insert a new document and query for the latest one. It should be the same, right. But it's not.
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 }
I also tried to iterate all the documents (both from the command line and using Robomongo. I get the same result in both):
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 }
As you can see the last document is the one the query above also returned, not the latest document I inserted.
Is there something to Mongo or Mongolab that I don't understand, or should this work - but it doesn't for some reason?
Upvotes: 1
Views: 192
Reputation: 4117
You should never rely on the natural order to give you a consistent ordering.
I'll quote the docs on this:
Typically, the natural order reflects insertion order, except when documents relocate because of document growth due to updates or remove operations free up space which are then taken up by newly inserted documents.
You can expect a more consistent behaviour by sorting the documents by _id (read Adam's answer about this). However, even this can fail:
The relationship between the order of ObjectId values and generation time is not strict within a single second. If multiple systems, or multiple processes or threads on a single system generate values, within a single second; ObjectId values do not represent a strict insertion order. Clock skew between clients can also result in non-strict ordering even for values, because client drivers generate ObjectId values, not the mongod process.
Creating a specific field for that purpose (like a date) and indexing it would probably be the best and easiest approach.
Upvotes: 1
Reputation: 5539
While it can seem otherwise with a new, small collection, natural order is not the same as insert order. Natural order returns documents in the order they're referred to by the collection's internal data structures, which is optimized for performance rather than keeping track of insert time.
http://docs.mongodb.org/manual/reference/operator/meta/natural/
If you'd like to sort documents by the time of some event related to each document (e.g. insert time, last updated time), I'd recommend tracking that time explicitly as a field, indexing that field, and then sorting by it in your queries.
Upvotes: 2