如果没有指定排序顺序,MongoDB 如何记录排序?

当我们在没有指定任何排序顺序的情况下运行 Mongo find ()查询时,数据库内部使用什么来对结果进行排序?

根据 Mongo 网站上的文件:

当执行没有参数的 find ()时,数据库将返回 自然顺序向前的物体。

对于标准表,自然顺序并不特别有用,因为, 虽然顺序通常接近插入顺序,但它不是 但是,对于有上限的收集,自然秩序是 保证是插入顺序。这可能非常有用。

但是对于标准集合(无上限集合) ,使用哪个字段对结果进行排序? 是 身份证字段还是别的什么?

编辑:

基本上,我想我试图得到的是,如果我执行以下搜索查询:

db.collection.find({"x":y}).skip(10000).limit(1000);

在两个不同的时间点: T1T2,我将得到不同的结果集:

  1. 当在 t1和 t2之间没有额外的写操作时?
  2. 什么时候在 t1和 t2之间有新的写入?
  3. 在 t1和 t2之间添加了新的索引?

我已经在一个临时数据库上运行了一些测试,我得到的结果是相同的(是的) ,所有3个案例-但我想确定,我确定我的测试案例不是很彻底。

49848 次浏览

它按照存储顺序(文件中的顺序)返回,但不能保证它们是按照插入的顺序返回的。它们不按 _ id 字段排序。有时它看起来像是按插入顺序排序的,但它可以在另一个请求中更改。这是不可靠的。

当没有指定排序顺序时,默认排序顺序是什么?

默认的内部排序顺序(或 自然秩序)是 未定义实现细节。维护顺序是存储引擎的额外开销,MongoDB 的 API 并不要求在显式 sort()之外的可预测性,或者与 使用限制相关联的固定大小的 封顶收藏的特殊情况。对于典型的工作负载,存储引擎需要尝试重用可用的预分配空间,并决定如何最有效地将数据存储在磁盘和内存中。

如果没有任何查询条件,结果将由 自然秩序(又名 按发现的顺序排列)中的存储引擎返回。结果顺序可能与插入顺序一致,但是这种行为不能保证,也不能依赖(除了有上限的集合)。

一些可能影响存储(自然)顺序的例子:

  • WiredTiger 使用不同于内存缓存的磁盘文档表示形式,因此自然排序可能会根据内部数据结构而改变。
  • 最初的 MMAPv1存储引擎(在 MongoDB 4.2中删除)根据填充规则为文档分配记录空间。如果文档超出了当前分配的记录空间,文档位置(和自然排序)将受到影响。还可以将新文档插入标记为可重用的存储区中,这些存储区由于文档被删除或移动而可重用。
  • 复制使用 幂等 oplog 幂等的 oplog格式在复制集成员之间一致地应用写操作。每个副本集成员维护本地数据文件,这些文件可以按自然顺序变化,但在应用 oplog 更新时具有相同的数据结果。

如果使用索引会怎样?

如果使用索引,文档将按照找到的顺序返回(这必然与插入顺序或 I/O 顺序匹配)。如果使用了多个索引,那么顺序在内部取决于在删除重复数据过程中哪个索引首先标识了文档。

如果需要可预测的排序顺序,则 必须的在查询中包含显式的 sort(),并且排序键具有唯一的值。

有上限的集合如何维护插入顺序?

在有上限的集合中,为自然顺序注意到的实现异常通过其特殊的使用限制来实现: 文档按插入顺序存储,但不能增加现有文档的大小,也不能显式删除文档。排序是封顶集合设计的一部分,它确保最古老的文档首先“过时”。