我是MongoDB的新手,但我似乎对Herola使用的Mongolab有一个小问题。
如果我插入新文档,我不会收到任何错误。但Mongolab的MongoDB似乎在某个文档之后没有返回任何文档。也不是我插入的最新文档。
这是一个例子;我插入一个新文档并查询最新文档。它应该是一样的,对吧。但事实并非如此。
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有什么我不明白的东西,或者这应该有用吗 - 但它不是出于某种原因吗?
答案 0 :(得分:2)
虽然在新的小集合中看起来似乎不同,但自然顺序与插入顺序不同。自然顺序按照集合的内部数据结构的顺序返回文档,这些数据结构针对性能进行了优化,而不是跟踪插入时间。
http://docs.mongodb.org/manual/reference/operator/meta/natural/
如果您希望在与每个文档相关的某些事件(例如插入时间,上次更新时间)之前对文档进行排序,我建议将该时间明确地作为字段进行跟踪,将该字段编入索引,然后在查询中按它排序。
答案 1 :(得分:1)
您永远不应该依赖自然顺序来为您提供一致的排序。
我会在此引用docs:
通常,自然顺序反映了插入顺序,除非是 由于更新或删除文档增长导致文档重定位 操作释放空间,然后由新插入的空间占用 文档。
通过_id排序文档可以预期更一致的行为(请阅读Adam's answer)。但是,即使是this can fail:
ObjectId值的顺序与生成之间的关系 时间在一秒钟内不严格。如果是多个系统,或者 单个系统上的多个进程或线程生成值, 在一秒钟内; ObjectId值不代表严格 插入顺序。客户端之间的时钟偏差也可能导致 因为客户端驱动程序生成,所以即使是值也不严格排序 ObjectId值,而不是mongod进程。
为此目的创建特定字段(如日期)并将其编入索引可能是最好和最简单的方法。