MongoDB find()查询是否返回按创建时间排序的文档?
我需要按创建时间(从最早到最新)排序的文档 由于ObjectID默认保存时间戳,因此我们可以使用它通过MongoDB find()查询是否返回按创建时间排序的文档?,mongodb,sorting,database,Mongodb,Sorting,Database,我需要按创建时间(从最早到最新)排序的文档 由于ObjectID默认保存时间戳,因此我们可以使用它通过CollectionName.find().sort({u id:1})按创建时间对文档进行排序 另外,我注意到常规的CollectionName.find()query总是以与CollectionName.find().sort({u id:1})相同的顺序返回文档 我的问题是: CollectionName.find()是否保证以与CollectionName.find().sort({u
CollectionName.find().sort({u id:1})
按创建时间对文档进行排序
另外,我注意到常规的
CollectionName.find()
query总是以与CollectionName.find().sort({u id:1})
相同的顺序返回文档
我的问题是:
CollectionName.find()
是否保证以与CollectionName.find().sort({u id:1})
相同的顺序返回文档,以便我可以不进行排序
CollectionName.find()是否保证以与CollectionName.find().sort({u id:1})相同的顺序返回文档
不,不是如果未指定任何顺序,则使用所谓的“自然”顺序。这意味着文档将按照它们在数据文件中实际出现的顺序返回
现在,如果您只插入文档而从不修改它们,那么这种自然顺序将与递增的\u id
顺序一致。但是,想象一下,您以这样的方式更新文档,文档的大小会增加,并且必须移动到数据文件内部的空闲插槽中(通常这意味着文件末尾的某个位置)。如果您现在查询文档,它们将不会遵循任何合理的(外部观察者)顺序
所以,如果你关心秩序,就把它说清楚
资料来源:
自然秩序
数据库引用磁盘上文档的顺序。这是默认的排序顺序。请参阅$natural并按自然顺序返回
测试脚本(针对困惑的用户)
>db.foo.insert({name:'Joe'})
WriteResult({“n插入”:1})
>db.foo.insert({name:'Bob'})
WriteResult({“n插入”:1})
>db.foo.find()
{“_id”:ObjectId(“55814b944e019172b7d358a0”),“name”:“Joe”}
{“_id”:ObjectId(“55814ba44e019172b7d358a1”),“name”:“Bob”}
>db.foo.update({u id:ObjectId(“55814b944e019172b7d358a0”)},{$set:{答案:"在分片集合上,$natural运算符返回按自然顺序排序的集合扫描,即数据库在磁盘上插入和存储文档的顺序。包含按$natural顺序排序的查询不使用索引来实现查询谓词,但以下情况除外:如果查询谓词是_id字段上的相等条件{{u id:},则具有按$natural顺序排序的查询可以使用{u id索引。如果查询包含$text表达式,则不能指定$natural排序顺序。“})
WriteResult({“nMatched”:1,“nUpserted”:0,“nModified”:1})
>db.foo.find()
{“_id”:ObjectId(“55814ba44e019172b7d358a1”),“name”:“Bob”}
{“_id”:ObjectId(“55814b944e019172b7d358a0”),“姓名”:“乔”,“答案”:”在分片集合上,$natural运算符返回按自然顺序排序的集合扫描,即数据库在磁盘上插入和存储文档的顺序。包含按$natural顺序排序的查询不使用索引来实现查询谓词,但以下情况除外:如果查询谓词是_id字段上的相等条件{{u id:},则具有按$natural顺序排序的查询可以使用{u id索引。如果查询包含$text表达式,则不能指定$natural排序顺序。“}
不,不完全是这样。
db.collection.find()
结果排序
除非指定sort()方法或使用$near运算符,否则MongoDB不保证查询结果的顺序
只要您的数据文件相对较新,并且很少发生更新,文档就可能(而且大多数情况下都会)按\u id
排序返回,因为ObjectId是单调递增的
在生命周期的后期,旧文档可能已从其旧位置移动(因为它们的大小增加,并且文档从未分区),而新文档则在以前被另一个文档占用的位置写入。在这种情况下,新文档可能会返回到两个旧文档之间的位置
按\u id
对文档进行排序没有什么错,因为索引将用于排序,只会为文档检索增加一些延迟
但是,出于以下几个原因,我强烈建议不要将ObjectId用于日期操作:
ObjectId不能用于日期比较查询。因此,您无法查询在日期x和日期y之间创建的所有文档。若要存档,您必须加载所有文档,从ObjectId中提取日期并进行比较,这是非常低效的
如果创建日期很重要,则应在文档中明确说明
我将ObjectId视为最后一种方法,用于\u id
字段,并且倾向于将其他值(有时使用复合)作为\u id
s,因为该字段默认为索引,并且很可能通过使用更有意义的值作为id来保存宝贵的RAM
您可以使用下面的示例,它利用
并且使用
db.collection.find().sort({_id.creationDate:1})
“自然”顺序只能通过使用.sort({“$Natural”:1})
来实现。这是请求数据“按存储在磁盘上的顺序”的唯一方法。此外,由于“磁盘上的数据”可以“移动”(并且经常移动),因此这不是“插入顺序”.仔细阅读,这个答案并不声称自然顺序与插入顺序相同。事实上,整个答案都是关于它如何不同。引用:“如果你没有指定任何顺序,那么就使用所谓的“自然”顺序”。你的话不是我的。那不是真的。是的,自然顺序,不是插入顺序。此测试无效。分片集合使用“分片键”进行选择,可能使用“分散-聚集”。因此主键不是
{
_id: {
creationDate: new ISODate(),
user: {
"$ref" : "creators",
"$id" : "mwmahlberg",
"$db" : "users"
}
}
}
db.collection.find().sort({_id.creationDate:1})