无法 return 来自 MongoDB 的最新文档

Cannot return latest documents from MongoDB

我对 MongoDB 很陌生,但是我在 Heroku 中使用的 Mongolab 似乎有一个小问题。

如果我插入一个新文档,我不会收到任何错误。但是 Mongolab 的 MongoDB 似乎没有 return 某个文件之后的任何文件。也不是我插入的最新文档。

举个例子;我插入一个新文档并查询最新的文档。应该是一样的吧。但事实并非如此。

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 }

如您所见,最后一个文档是上面的查询也是 returned,而不是我插入的最新文档。

Mongo 或 Mongolab 有什么我不明白的地方吗?

虽然对于一个新的、小的集合看起来可能不是这样,但自然顺序与插入顺序不同。自然顺序 returns 文档按照集合内部数据结构引用的顺序排列,该顺序针对性能进行了优化,而不是跟踪插入时间。

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

如果您想按与每个文档相关的某些事件的时间对文档进行排序(例如插入时间、上次更新时间),我建议将该时间明确地作为一个字段进行跟踪,为该字段建立索引,然后然后在您的查询中按它排序。

您永远不应依赖自然顺序来为您提供一致的顺序。

我将引用docs

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.

您可以通过按 _id 对文档进行排序来获得更一致的行为(阅读 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.

为此目的创建一个特定字段(如日期)并为其编制索引可能是最好和最简单的方法。