我需要按创建时间(从最旧到最新)排序的文档。
由于ObjectID默认保存时间戳,我们可以使用它来获取按创建时间CollectionName.find().sort({_id: 1})
排序的文档。
另外,我注意到常规CollectionName.find()
查询始终会以相同顺序返回与CollectionName.find().sort({_id: 1})
相同的文档。
我的问题是:
CollectionName.find()
是否保证以与CollectionName.find().sort({_id: 1})
相同的顺序返回文档,以便我可以将整理出来?
答案 0 :(得分:4)
CollectionName.find()保证以与CollectionName.find()相同的顺序返回文档.sort({_ id:1})
不,它不是!如果您没有指定任何订单,那么所谓的"自然"使用订购。这意味着文档将按照它们实际出现在数据文件中的顺序返回。
现在,如果您只插入文档而从不修改它们,则此自然顺序将与升序_id
顺序一致。但是,想象一下,您以一种大小增长的方式更新文档,并且必须将其移动到数据文件内的空闲插槽(通常这意味着文件末尾的某处)。如果您现在要查询文档,他们就不会遵循任何合理的(对外部观察员)订单。
因此,如果您关心订单,请明确说明。
来源:http://docs.mongodb.org/manual/reference/glossary/#term-natural-order
自然顺序
数据库引用磁盘上文档的顺序。这是默认的排序顺序。参见$ natural和Return in Natural Order。
> db.foo.insert({name: 'Joe'})
WriteResult({ "nInserted" : 1 })
> db.foo.insert({name: 'Bob'})
WriteResult({ "nInserted" : 1 })
> db.foo.find()
{ "_id" : ObjectId("55814b944e019172b7d358a0"), "name" : "Joe" }
{ "_id" : ObjectId("55814ba44e019172b7d358a1"), "name" : "Bob" }
> db.foo.update({_id: ObjectId("55814b944e019172b7d358a0")}, {$set: {answer: "On a sharded collection the $natural operator returns a collection scan sorted in natural order, the order the database inserts and stores documents on disk. Queries that include a sort by $natural order do not use indexes to fulfill the query predicate with the following exception: If the query predicate is an equality condition on the _id field { _id: <value> }, then the query with the sort by $natural order can use the _id index. You cannot specify $natural sort order if the query includes a $text expression."}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find()
{ "_id" : ObjectId("55814ba44e019172b7d358a1"), "name" : "Bob" }
{ "_id" : ObjectId("55814b944e019172b7d358a0"), "name" : "Joe", "answer" : "On a sharded collection the $natural operator returns a collection scan sorted in natural order, the order the database inserts and stores documents on disk. Queries that include a sort by $natural order do not use indexes to fulfill the query predicate with the following exception: If the query predicate is an equality condition on the _id field { _id: <value> }, then the query with the sort by $natural order can use the _id index. You cannot specify $natural sort order if the query includes a $text expression." }
答案 1 :(得分:4)
没有。好吧,不完全是。
db.collection.find()
将按照它们在数据文件主机中出现的顺序为您提供文档,但这不能保证。
结果排序
除非指定sort()方法或使用$ near运算符,否则MongoDB不保证查询结果的顺序。
只要您的数据文件相对较新并且几乎没有更新,文档可能(并且大部分时间)将以_id
的方式返回,因为ObjectId是单调增加的。
在生命周期的后期,旧文档可能已经从旧位置移开(因为它们的大小增加,文档从未被分区),而新文档则被写入以前由另一个文档占用的位置。在这种情况下,可以在两个旧文档之间的位置返回较新的文档。
按_id
排序文档没有任何问题,因为索引将用于此,只为文档检索添加一些延迟。
但是,我强烈建议不要将ObjectId用于日期操作,原因如下:
_id
字段的最后选择,并倾向于使用其他值(偶尔复合)作为_id
,因为该字段默认为索引,并且非常很可能通过使用更有意义的值作为id来节省宝贵的RAM。您可以使用以下内容,例如使用DBRef s
{
_id: {
creationDate: new ISODate(),
user: {
"$ref" : "creators",
"$id" : "mwmahlberg",
"$db" : "users"
}
}
}
使用
做一个非常便宜的排序db.collection.find().sort({_id.creationDate:1})