如果没有指定,默认的排序顺序是什么?
默认的内部排序顺序(或natural order)是undefined实现细节.维护订单对存储引擎来说是额外的开销,MongoDB的API不要求在显式sort()
或固定大小capped collections的特例之外具有可预测性,而固定大小capped collections与usage restrictions相关.对于典型的工作负载,存储引擎需要try 重用可用的预分配空间,并决定如何最有效地将数据存储在磁盘和内存中.
如果没有任何查询条件,存储引擎将在natural order(又名in the order they are found)中返回结果.结果顺序可能与插入顺序一致,但这种行为不能保证,也不能依赖(封顶集合除外).
可能影响存储(自然)顺序的一些示例:
- WiredTiger对磁盘上的文档和内存缓存中的文档使用不同的表示形式,因此自然排序可能会根据内部数据 struct 而改变.
- 原始的MMAPv1存储引擎(在MongoDB 4.2中删除)根据填充规则为文档分配记录空间.如果文档超出当前分配的记录空间,文档位置(和自然顺序)将受到影响.还可以将新文档插入到标记为可供删除或移动的文档重新使用的存储器中.
- 复制使用idempotent oplog格式在副本集成员之间一致地应用写操作.每个副本集成员维护本地数据文件,这些文件可以按自然顺序变化,但在应用oplog更新时,数据结果将相同.
如果使用索引呢?
如果使用索引,文档将按找到的顺序返回(这必然与插入顺序或I/O顺序匹配).如果使用了多个索引,则顺序在内部取决于在重复数据消除过程中首先识别文档的索引.
如果想要可预测的排序顺序,可以在查询中包含一个显式的sort()
,并为排序键提供唯一的值.
封顶集合如何维护插入顺序?
capped collections中自然顺序的实现例外是由其特殊的使用限制强制执行的:文档以插入顺序存储,但不能增加现有文档的大小,也不能显式删除文档.订购是封顶Collection 设计的一部分,可确保最古老的文档首先"过时".