$sort (aggregation)

On this page本页内容

Definition定义

$sort

Sorts all input documents and returns them to the pipeline in sorted order.对所有输入文档进行排序,并按排序顺序将其返回管道。

The $sort stage has the following prototype form:$sort阶段具有以下原型形式:

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

$sort takes a document that specifies the field(s) to sort by and the respective sort order. 获取一个文档,该文档指定要排序的字段和相应的排序顺序。<sort order> can have one of the following values:可以具有以下值之一:

ValueDescription描述
1 Sort ascending.升序排序。
-1 Sort descending.按降序排序。
{ $meta: "textScore" } Sort by the computed textScore metadata in descending order. 按计算出的textScore元数据按降序排序。See Text Score Metadata Sort for an example.有关示例,请参阅文本分数元数据排序

If sorting on multiple fields, sort order is evaluated from left to right. 如果在多个字段上排序,排序顺序将从左到右计算。For example, in the form above, documents are first sorted by <field1>. 例如,在上面的表单中,文档首先按<field1>排序。Then documents with the same <field1> values are further sorted by <field2>.然后,具有相同<field1>值的文档将按<field2>进一步排序。

Behavior行为

Sort Stability排序稳定性

In MongoDB, sorts are inherently stable, unless sorting on a field which contains duplicate values:在MongoDB中,排序本质上是稳定的,除非对包含重复值的字段进行排序:

  • a stable sort is one that returns the same sort order each time it is performed稳定排序是每次执行时返回相同排序顺序的排序
  • an unstable sort is one that may return a different sort order when performed multiple times不稳定排序是指在多次执行时可能返回不同排序顺序的排序

If a stable sort is desired, include at least one field in your sort that contains exclusively unique values. 如果需要稳定排序,请在排序中至少包含一个包含唯一值的字段。The easiest way to guarantee this is to include the _id field in your sort query.保证这一点的最简单方法是在排序查询中包含_id字段。

Consider the following restaurant collection:考虑以下restaurant集合:

db.restaurants.insertMany( [
   { "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan"},
   { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens"},
   { "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn"},
   { "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan"},
   { "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn"},
] );

The following command uses the $sort stage to sort on the borough field:以下命令使用$sort阶段在borough字段上进行排序:

db.restaurants.aggregate(
   [
     { $sort : { borough : 1 } }
   ]
)

In this example, the sort is unstable, since the borough field contains duplicate values for both Manhattan and Brooklyn. 在本例中,排序是不稳定的,因为borough字段包含ManhattanBrooklyn的重复值。Documents are returned in alphabetical order by borough, but the order of those documents with duplicate values for borough might not the be the same across multiple executions of the same sort. 文档是按borough的字母顺序返回的,但是在多次执行相同的排序时,那些具有重复borough值的文档的顺序可能不同。For example, here are the results from two different executions of the above command:例如,以下是上述命令的两次不同执行的结果:

{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" }
{ "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" }
{ "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" }
{ "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" }

{ "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" }
{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" }
{ "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" }
{ "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" }

While the values for borough are still sorted in alphabetical order, the order of the documents containing duplicate values for borough (i.e. Manhattan and Brooklyn) is not the same.虽然borough的值仍按字母顺序排序,但包含重复的borough值(即ManhattanBrooklyn)的文档的顺序是不一样的。

To achieve a stable sort, add a field which contains exclusively unique values to the sort. 要实现稳定排序,请在排序中添加一个包含唯一值的字段。The following command uses the $sort stage to sort on both the borough field and the _id field:以下命令使用$sort阶段在borough字段和_id字段上进行排序:

db.restaurants.aggregate(
   [
     { $sort : { borough : 1, _id: 1 } }
   ]
)

Since the _id field is always guaranteed to contain exclusively unique values, the returned sort order will always be the same across multiple executions of the same sort.由于_id字段始终保证包含唯一的值,因此在同一排序的多次执行中,返回的排序顺序始终相同。

Examples示例

Ascending/Descending Sort升序/降序排序

For the field or fields to sort by, set the sort order to 1 or -1 to specify an ascending or descending sort respectively, as in the following example:对于要排序的一个或多个字段,请将排序顺序设置为1-1,以分别指定升序或降序排序,如下例所示:

db.users.aggregate(
   [
     { $sort : { age : -1, posts: 1 } }
   ]
)

This operation sorts the documents in the users collection, in descending order according by the age field and then in ascending order according to the value in the posts field.此操作将users集合中的文档按age字段按降序排序,然后按post字段中的值按升序排序。

When comparing values of different BSON types, MongoDB uses the following comparison order, from lowest to highest:在比较不同BSON类型的值时,MongoDB使用以下比较顺序,从最低到最高:

  1. MinKey (internal type)
  2. Null
  3. Numbers (ints, longs, doubles, decimals)
  4. Symbol, String
  5. Object
  6. Array
  7. BinData
  8. ObjectId
  9. Boolean
  10. Date
  11. Timestamp
  12. Regular Expression
  13. MaxKey (internal type)

For details on the comparison/sort order for specific types, see Comparison/Sort Order.有关特定类型的比较/排序顺序的详细信息,请参阅比较/排序顺序

Text Score Metadata Sort文本分数元数据排序

For a pipeline that includes a $text search, you can sort by descending relevance score using the { $meta: "textScore" } expression. 对于包含$text搜索的管道,可以使用{ $meta: "textScore" }表达式通过降低相关性分数进行排序。In the { <sort-key> } document, set the { $meta: "textScore" } expression to an arbitrary field name. { <sort-key> }文档中,将{ $meta: "textScore" }表达式设置为任意字段名。The field name is ignored by the query system. 查询系统将忽略字段名。For example:例如:

db.users.aggregate(
   [
     { $match: { $text: { $search: "operating" } } },
     { $sort: { score: { $meta: "textScore" }, posts: -1 } }
   ]
)

This operation uses the $text operator to match the documents, and then sorts first by the "textScore" metadata in descending order, and then by the posts field in descending order. 此操作使用$text运算符匹配文档,然后首先按"textScore"元数据降序排序,然后按posts字段降序排序。The score field name in the sort document is ignored by the query system. 查询系统将忽略排序文档中的score字段名称。In this pipeline, the "textScore" metadata is not included in the projection and is not returned as part of the matching documents. 在这个管道中,"textScore"元数据不包括在投影中,也不会作为匹配文档的一部分返回。See $meta for more information.更多信息请参见$meta

$sort Operator and Memory运算符和内存

$sort + $limit Memory Optimization内存优化

When a $sort precedes a $limit and there are no intervening stages that modify the number of documents, the optimizer can coalesce the $limit into the $sort. $sort先于$limit,并且没有修改文档数量的中间阶段时,优化器可以将$limit合并到$sort中。This allows the $sort operation to only maintain the top n results as it progresses, where n is the specified limit, and ensures that MongoDB only needs to store n items in memory. 这允许$sort操作在进行时只维护前n个结果,其中n是指定的限制,并确保MongoDB只需要在内存中存储n个项。This optimization still applies when allowDiskUse is true and the n items exceed the aggregation memory limit.allowDiskUsetruen项超过聚合内存限制时,此优化仍然适用。

Optimizations are subject to change between releases.优化可能会在不同版本之间发生变化。

$sort and Memory Restrictions和内存限制

The $sort stage has a limit of 100 megabytes of RAM. $sort阶段的内存限制为100兆字节。By default, if the stage exceeds this limit, $sort will produce an error. 默认情况下,如果阶段超过此限制,$sort将产生错误。To allow for the handling of large datasets, set the allowDiskUse option to true to enable $sort operations to write to temporary files. 要允许处理大型数据集,请将allowDiskUse选项设置为true,以允许$sort操作写入临时文件。See the allowDiskUse option in db.collection.aggregate() method and the aggregate command for details.请参见db.collection.aggregate()方法中的allowDiskUse选项和aggregate命令以获取详细信息。

$sort Operator and Performance运算符和性能

$sort operator can take advantage of an index as long as it is not preceded by a $project, $unwind, or $group stage.$sort运算符可以利用索引,只要它前面没有$project$unwind$group阶段。