在我的 User 集合中,MongoDB通常按照我创建的顺序对每个新文档进行排序:创建的最后一个是集合中的最后一个。但我已经检测到另一个集合,其中我创建的最后一个集合在27个文档之间具有6个位置。
为什么?
MongoDB集合中的每个文档都遵循哪个顺序?
答案 0 :(得分:22)
它被称为natural order:
natural order
数据库引用磁盘上文档的顺序。这是默认的排序顺序。请参阅
$natural
和Return in Natural Order
。
这证实了一般情况下,你按照你输入的顺序得到它们,但这并不能保证 - 正如你所注意到的那样。
Return in Natural Order
$natural
参数根据数据库中的natural order返回项目。此排序是一个内部实现功能,您不应该依赖其中的任何特定结构。Index Use
包含按
$natural
顺序排序的查询不使用索引来完成查询谓词,但出现以下异常:如果查询谓词是{{1}上的相等条件} field_id
,然后按$natural
顺序排序的查询可以使用{ _id: <value> }
索引。MMAPv1
通常,自然顺序反映了插入顺序,MMAPv1存储引擎具有以下例外。对于MMAPv1存储引擎,如果文档由于document growth而重新定位,则自然顺序不反映插入顺序,或者删除操作释放空间,然后由新插入的文档占用空间。
显然,就像上面提到的文档一样,你应该不依赖这个默认顺序(这个顺序是一个内部实现功能,你不应该依赖它内部的任何特定结构。< / em>的)。
如果您需要对事物进行排序,请使用sort solutions。
基本上,以下两个调用应该以相同的顺序返回文档(因为默认顺序是_id
):
$natural
如果您想按其他字段排序(例如db.mycollection.find().sort({ "$natural": 1 })
db.mycollection.find()
),您可以这样做:
name
答案 1 :(得分:2)
MongoDB根本没有“订购”文件,除非你提出要求。
基本插入将在_id
主键值中创建ObjectId
,除非您告诉它不这样做。此ObjectId
值是具有"monotonic"或“不断增加”属性的特殊值,这意味着创建的每个值都保证大于最后一个值。
如果你想要“排序”,那么做一个明确的“排序”:
db.collection.find().sort({ "_id": 1 })
或"natural"排序表示存储在磁盘上的顺序:
db.collection.find().sort({ "$natural": 1 })
除非另有说明,否则这几乎是标准,或者由确定排序顺序的查询条件选择“索引”。但是,如果查询条件选择了另外排序的索引,则可以使用它来“强制”该顺序。
MongoDB文档在成长时“移动”,因此_id
顺序并不总是与检索文档的顺序明确相同。
答案 2 :(得分:2)
出于性能原因,MongoDB从不在硬盘上拆分文档。
当你从一个空的集合开始并开始在文档之后插入文档时,mongoDB会将它们连续放在磁盘上。
但是当您更新文档并且现在需要更多空间并且不再适合其旧位置而不重叠下一个文档时会发生什么?在这种情况下,MongoDB将删除它并在集合文件的末尾将其重新附加为新的。
您的收藏文件现在有一个未使用的空间。这是相当浪费的,不是吗?这就是为什么下一个插入并足够小以适合该孔的文件将插入该孔中的原因。这可能是你第二次收集的情况。
底线:永远不要依赖按插入顺序返回的文档。当您关心订单时,请始终对结果进行排序。
答案 3 :(得分:2)
由于Return in Natural Order提供的链接Ionică Bizău,我可以找到更多相关信息。
“$ natural参数根据数据库中的自然顺序返回项目。此排序是内部实现功能,您不应该依赖其中的任何特定结构。
通常,自然顺序反映了插入顺序,MMAPv1存储引擎具有以下例外。 对于MMAPv1存储引擎,如果文档由于文档增长而重新定位,或者删除操作释放空间,然后由新插入的文档占用,则自然顺序不会反映插入顺序。“