cursor.sort()

在本页面

Definition

  • cursor. sort(* sort *)
    • 指定查询返回匹配文档的 Sequences。从数据库中检索任何文档之前,必须将sort()应用于光标。

sort()方法具有以下参数:

ParameterTypeDescription
sortdocument定义结果集排序 Sequences 的文档。

sort参数包含字段和值对,格式如下:

{ field: value }

排序文档可以指定对现有字段进行升序或降序排序对计算的元数据进行排序

Behaviors

Result Ordering

除非您指定sort()方法或使用$near运算符,否则 MongoDB 不能保证查询结果的 Sequences。

Ascending/Descending Sort

在 sort 参数中指定要作为排序依据的一个或多个字段,并指定值1-1分别指定升序或降序。

下面的示例文档按age字段指定降序排列,然后按posts字段指定升序排列:

{ age : -1, posts: 1 }

比较不同BSON types的值时,MongoDB 使用以下比较 Sequences,从最低到最高:

  • MinKey(内部类型)

  • Null

  • 数字(整数,整数,双精度数,小数)

  • Symbol, String

  • Object

  • Array

  • BinData

  • ObjectId

  • Boolean

  • Date

  • Timestamp

  • Regular Expression

  • MaxKey(内部类型)

有关特定类型的比较/排序 Sequences 的详细信息,请参见Comparison/Sort Order

Metadata Sort

在 sort 参数中为计算的元数据指定新的字段名称,并将$meta表达式指定为其值。

以下 samples 文档按"textScore"元数据指定降序排列:

{ score: { $meta: "textScore" } }

指定的元数据确定排序 Sequences。例如,"textScore"元数据按降序排序。有关详情,请参见$meta

Restrictions

当无法从索引获取排序 Sequences 时,MongoDB 将对内存中的结果进行排序,这要求要排序的结果集小于 32 兆字节。

当排序操作消耗的内存超过 32 MB 时,MongoDB 返回错误。为避免此错误,请创建支持排序操作的索引(请参见排序和索引使用)或将sort()limit()结合使用(请参见Limit Results)。

排序和索引使用

有时可以通过按 Sequences 扫描索引来满足排序要求。如果查询计划使用索引来提供请求的排序 Sequences,则 MongoDB 不会对结果集执行内存中排序。有关更多信息,请参见使用索引对查询结果进行排序

Limit Results

您可以将sort()limit()结合使用以返回第一个(按排序 Sequences)k文档,其中k是指定的限制。

如果 MongoDB 无法通过索引扫描获得排序 Sequences,则 MongoDB 使用 top-k 排序算法。此算法缓冲到目前为止基础索引或集合访问看到的前k个结果(或最后一个,取决于排序 Sequences)。如果这些k结果的内存占用量在任何时候都超过 32 兆字节,则查询将失败。

与投影的互动

当一组结果都经过排序和投影时,MongoDB 查询引擎将始终应用 first

Examples

集合orders包含以下文档:

{ _id: 1, item: { category: "cake", type: "chiffon" }, amount: 10 }
{ _id: 2, item: { category: "cookies", type: "chocolate chip" }, amount: 50 }
{ _id: 3, item: { category: "cookies", type: "chocolate chip" }, amount: 15 }
{ _id: 4, item: { category: "cake", type: "lemon" }, amount: 30 }
{ _id: 5, item: { category: "cake", type: "carrot" }, amount: 20 }
{ _id: 6, item: { category: "brownies", type: "blondie" }, amount: 10 }

以下查询返回orders集合中的所有文档,但未指定排序 Sequences:

db.orders.find()

查询以不确定的 Sequences 返回文档:

{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }

以下查询在amount字段上以降序指定排序。

db.orders.find().sort( { amount: -1 } )

该查询以amount降序返回以下文档:

{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }
{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }

以下查询使用嵌入式文档item中的字段指定排序 Sequences。该查询首先按category字段升序排序,然后在每个category内按type字段升序排序。

db.orders.find().sort( { "item.category": 1, "item.type": 1 } )

该查询返回以下文档,首先按category字段排序,然后在每个类别中按type字段排序:

{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }
{ "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 }
{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 }
{ "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 }
{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 }
{ "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }

以自然 Sequences 返回

$natural参数根据数据库中的natural order返回项目。此排序是内部实现功能,您不应依赖其中的任何特定结构。

Note

您不能在视图上指定$natural排序。

Index Use

包含按$naturalSequences 排序的查询不使用索引来满足查询谓词,但有以下 exceptions:如果查询谓词是_id字段{ _id: <value> }上的相等条件,则按$naturalSequences 排序的查询可以使用_id索引。

MMAPv1

通常,自然 Sequences 反映插入 Sequences,但 MMAPv1 存储引擎具有以下 exception。对于 MMAPv1 存储引擎,如果文档由于document growth而重新定位,则自然 Sequences 不会反映插入 Sequences;或者删除操作会释放空间,然后这些空间会被新插入的文档占用。

考虑下面的示例,该示例使用 MMAPv1 存储引擎。

以下操作序列将文档插入trees集合:

db.trees.insert( { _id: 1, common_name: "oak", genus: "quercus" } )
db.trees.insert( { _id: 2, common_name: "chestnut", genus: "castanea" } )
db.trees.insert( { _id: 3, common_name: "maple", genus: "aceraceae" } )
db.trees.insert( { _id: 4, common_name: "birch", genus: "betula" } )

以下查询以自然 Sequences 返回文档:

db.trees.find().sort( { $natural: 1 } )

文档按以下 Sequences 返回:

{ "_id" : 1, "common_name" : "oak", "genus" : "quercus" }
{ "_id" : 2, "common_name" : "chestnut", "genus" : "castanea" }
{ "_id" : 3, "common_name" : "maple", "genus" : "aceraceae" }
{ "_id" : 4, "common_name" : "birch", "genus" : "betula" }

更新文档,使文档超出其当前分配的空间:

db.trees.update(
   { _id: 1 },
   { $set: { famous_oaks: [ "Emancipation Oak", "Goethe Oak" ] } }
)

重新运行查询以自然 Sequences 返回文档:

db.trees.find().sort( { $natural: 1 } )

对于使用 MMAPv1 的 MongoDB 实例,文档按以下自然 Sequences 返回,该 Sequences 不再反映插入 Sequences:

{ "_id" : 2, "common_name" : "chestnut", "genus" : "castanea" }
{ "_id" : 3, "common_name" : "maple", "genus" : "aceraceae" }
{ "_id" : 4, "common_name" : "birch", "genus" : "betula" }
{ "_id" : 1, "common_name" : "oak", "genus" : "quercus", "famous_oaks" : [ "Emancipation Oak", "Goethe Oak" ] }

See also