cursor.sort()

On this page本页内容

Definition定义

cursor.sort(sort)

mongo Shell Method

This page documents the mongo shell method, and does not refer to the MongoDB Node.js driver (or any other driver) method. 本页记录了mongo shell方法,未提及MongoDB Node.js驱动程序(或任何其他驱动程序)方法。For corresponding MongoDB driver API, refer to your specific MongoDB driver documentation instead.有关相应的MongoDB驱动程序API,请参阅特定的MongoDB驱动程序文档。

Specifies the order in which the query returns matching documents. 指定查询返回匹配文档的顺序。You must apply sort() to the cursor before retrieving any documents from the database.在从数据库检索任何文档之前,必须对游标应用sort()

The sort() method has the following parameter:sort()方法具有以下参数:

Parameter参数Type类型Description描述
sort document A document that defines the sort order of the result set.定义结果集排序顺序的文档。

The sort parameter contains field and value pairs, in the following form:sort参数包含字段和值对,形式如下:

{ field: value }

The sort document can specify ascending or descending sort on existing fields or sort on text score metadata.排序文档可以指定对现有字段进行升序或降序排序,或对文本分数元数据进行排序。

Behaviors行为

Sort Stability排序稳定性

Changed in version 4.4.在版本4.4中更改。

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() method to sort on the borough field:下面的命令使用sort()方法对borough字段进行排序:

db.restaurants.find().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() method to sort on both the borough field and the _id field:以下命令使用sort()方法对borough字段和_id字段进行排序:

db.restaurants.find().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字段始终保证包含唯一的值,因此在同一排序的多次执行中,返回的排序顺序始终相同。

Ascending/Descending Sort升序/降序排序

Specify in the sort parameter the field or fields to sort by and a value of 1 or -1 to specify an ascending or descending sort respectively.在sort参数中指定要排序的一个或多个字段,值为1-1分别指定升序或降序排序。

The following operation sorts the documents first by the age field in descending order and then by the posts field in ascending order:以下操作首先按age字段降序排列文档,然后按ports字段升序排列文档:

db.users.find({ }).sort( { age : -1, posts: 1 } )

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 $text search, you can sort by descending relevance score using the { $meta: "textScore" } expression.对于$text搜索,您可以使用{ $meta: "textScore" }表达式,通过降低相关性分数进行排序。

The following sample document specifies a descending sort by the "textScore" metadata:以下示例文档按"textScore"元数据指定了降序排序:

db.users.find(
   { $text: { $search: "operating" } },
   { score: { $meta: "textScore" }}        // Optional starting in MongoDB 4.4
).sort({ score: { $meta: "textScore" } })

The "textScore" metadata sorts in descending order."textScore"元数据按降序排序。

For more information, see $meta for details.有关更多信息,请参阅$meta以了解详细信息。

Sort and Index Use排序和索引使用

MongoDB can obtain the results of a sort operation from an index which includes the sort fields. MongoDB可以从包含排序字段的索引中获取排序操作的结果。MongoDB may use multiple indexes to support a sort operation if the sort uses the same indexes as the query predicate.如果排序使用与查询谓词相同的索引,MongoDB可以使用多个索引来支持排序操作。

If MongoDB cannot use an index or indexes to obtain the sort order, MongoDB must perform a blocking sort operation on the data. 如果MongoDB无法使用一个或多个索引来获取排序顺序,MongoDB必须对数据执行阻塞排序操作。A blocking sort indicates that MongoDB must consume and process all input documents to the sort before returning results. 阻塞排序表示MongoDB必须在返回结果之前使用并处理所有输入文档。Blocking sorts do not block concurrent operations on the collection or database.阻止排序不会阻止集合或数据库上的并发操作。

Sort operations that use an index often have better performance than blocking sorts. 使用索引的排序操作通常比阻塞排序具有更好的性能。For more information on creating indexes to support sort operations, see Use Indexes to Sort Query Results.有关创建索引以支持排序操作的更多信息,请参阅使用索引对查询结果进行排序

If MongoDB requires using more than 100 megabytes of system memory for the blocking sort operation, MongoDB returns an error unless the query specifies cursor.allowDiskUse() (New in MongoDB 4.4). 如果MongoDB需要使用超过100 MB的系统内存来执行阻塞排序操作,MongoDB将返回一个错误,除非查询指定cursor.allowDiskUse()MongoDB 4.4中新增)。allowDiskUse() allows MongoDB to use temporary files on disk to store data exceeding the 100 megabyte system memory limit while processing a blocking sort operation.允许MongoDB在处理阻塞排序操作时,使用磁盘上的临时文件存储超过100 MB系统内存限制的数据。

To check if MongoDB must perform a blocking sort, append cursor.explain() to the query and check the explain results. 要检查MongoDB是否必须执行阻塞排序,请将cursor.explain()附加到查询并检查解释结果。If the query plan contains a SORT stage, then MongoDB must perform a blocking sort operation subject to the 100 megabyte memory limit.如果查询计划包含SORT阶段,则MongoDB必须在100 MB内存限制下执行阻塞排序操作。

To prevent blocking sorts from consuming too much memory:要防止阻塞排序占用过多内存,请执行以下操作:

Limit Results限制结果

You can use sort() in conjunction with limit() to return the first (in terms of the sort order) k documents, where k is the specified limit.可以将sort()limit()结合使用,返回第一个(按照排序顺序)k个文档,其中k是指定的限制。

If MongoDB cannot obtain the sort order via an index scan, then MongoDB uses a top-k sort algorithm. 如果MongoDB无法通过索引扫描获得排序顺序,那么MongoDB将使用top-k排序算法。This algorithm buffers the first k results (or last, depending on the sort order) seen so far by the underlying index or collection access. 该算法缓冲底层索引或集合访问到目前为止看到的前k个结果(或最后一个,取决于排序顺序)。If at any point the memory footprint of these k results exceeds 100 megabytes, the query will fail unless the query specifies cursor.allowDiskUse() (New in MongoDB 4.4).如果在任何时候,这些k结果的内存占用超过100 MB,则查询将失败,除非查询指定cursor.allowDiskUse()MongoDB 4.4中新增)。

Interaction with Projection投影的交互作用

When a set of results are both sorted and projected, the MongoDB query engine will always apply the sorting first.当对一组结果进行排序和投影时,MongoDB查询引擎将始终首先应用排序。

Examples示例

A collection orders contain the following documents: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 }

The following query, which returns all documents from the orders collection, does not specify a sort order:以下查询返回orders集合中的所有文档,但未指定排序顺序:

db.orders.find()

The query returns the documents in indeterminate order:查询以不确定的顺序返回文档:

{ "_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 }

The following query specifies a sort on the amount field in descending order.以下查询按降序指定amount字段的排序。

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

The query returns the following documents, in descending order of amount:查询将按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 }

The following query specifies the sort order using the fields from an embedded document item. 以下查询使用嵌入文档item中的字段指定排序顺序。The query sorts first by the category field in ascending order, and then within each category, by the type field in ascending order.查询首先按category字段升序排序,然后在每个category内按type字段升序排序。

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

The query returns the following documents, ordered first by the category field, and within each category, by the type field:查询返回以下文档,首先按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 }

Return in Natural Order返回自然排序

The $natural parameter returns items according to their natural order within the database. $natural参数根据项目在数据库中的自然顺序返回项目。This ordering is an internal implementation feature, and you should not rely on any particular ordering of the documents.这种排序是一种内部实现功能,您不应该依赖于文档的任何特定排序。

Index Use索引使用

Queries that include a sort by $natural order do not use indexes to fulfill the query predicate with the following exception: If the query predicate is an equality condition on the _id field { _id: <value> }, then the query with the sort by $natural order can use the _id index.包含按$natural顺序排序的查询不使用索引来实现查询谓词,但以下情况除外:如果查询谓词是_id字段{ _id: <value> }上的相等条件,则具有按{ _id: <value> }顺序排序的查询可以使用_id索引。

See also参阅

$natural