未指定排序顺序时,MongoDB如何对记录进行排序?


103

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

根据mongo网站上文档

当执行不带参数的find()时,数据库将以自然前向顺序返回对象。

对于标准表,自然顺序并不是特别有用,因为尽管顺序通常接近插入顺序,但不能保证一定如此。但是,对于有上限的集合,可以保证自然顺序为插入顺序。这可能非常有用。

但是,对于标准馆藏(无上限馆藏),使用哪个字段对结果进行排序?是_id字段还是其他?

编辑:

基本上,我想尝试执行的是以下搜索查询:

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

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

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

我已经在临时数据库上运行了一些测试,对于这3种情况,我得到的结果都是相同的()-但我想确定一下,并且我肯定我的测试用例不是很全面。

Answers:


121

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

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

没有任何查询条件,结果将由存储引擎以自然顺序(也就是按照找到的顺序)返回。结果顺序可能与插入顺序一致,但是不能保证并且不能依赖此行为(除了上限集合外)。

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

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

如果使用索引怎么办?

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

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

封顶的收藏夹如何维护插入顺序?

受限制的集合中为自然顺序记录的实现例外是由其特殊的使用限制实施的:文档以插入顺序存储,但是无法增加现有文档的大小,也不能明确删除文档。订购是封顶收集设计的一部分,该设计可确保最旧的文档首先“过期”。


4
这是否意味着如果我在两个不同的时间点运行相同的find命令:db.collection.find({“ x”:y})。skip(20000).limit(1000),我将得到不同的结果套?如果两个命令之间没有写操作,会发生什么情况?
saurabhj 2012年

6
@saurabhj:添加了一些会影响自然秩序的示例。如果文档已被移动/删除,您可能会得到不同的结果集。如果没有文档插入/更新/删除,您应该得到相同的结果。添加索引不会影响文档在磁盘上的位置。
Stennie 2012年

7
还应注意,如果使用复制,则副本集成员之间的自然顺序可能会有所不同。
Stennie 2012年

有人知道如何强制此处评论的2分吗?我们尝试修改文档,但仍按插入顺序返回文档...我很好奇自然顺序是否可以与插入顺序不同。
Ferran Maylinch,

强制使用默认顺序(例如{createdAt: -1})来实现Optimistic UI模式(更新缓存中的数据列表,而无需在创建/更新/删除后等待服务器响应)。否则,您将无法匹配客户端乐观顺序和服务器响应顺序。
艾瑞克·伯瑞尔

8

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.