$rank (aggregation)
定义
版本 5.0 中的新增功能。
返回一个文档在 $setWindowFields
阶段分区中相对于其他文档的位置(称为排名)。
The sortBy field value in the
$setWindowFields
stage determines the document rank. When
used with the $rank
operator, sortBy
can only take one field as
its value. For more information on how MongoDB compares fields with
different types, see BSON comparison order.
If multiple documents occupy the same rank, $rank
places
the document with the subsequent value at a rank with a gap
(see 行为).
$rank
只能在 $setWindowFields
阶段使用。
$rank
语法:
{ $rank: { } }
$rank
不接受任何参数。
行为
$rank
和 $denseRank
differ in how they rank duplicate
sortBy field values. For example, with
sortBy field values of 7, 9, 9, and 10:
$denseRank
ranks the values as 1, 2, 2, and 3. The duplicate 9 values have a rank of 2, and 10 has a rank of 3. There is no gap in the ranks.$rank
ranks the values as 1, 2, 2, and 4. The duplicate 9 values have a rank of 2, and 10 has a rank of 4. There is a gap in the ranks for 3.
sortBy 字段值为 null
的文档或缺少 sortBy 字段的文档根据 BSON 比较顺序分配排名。
See the example in Rank Partitions Containing Duplicate Values, Nulls, or Missing Data.
示例
创建cakeSales
集合,其中包含加利福尼亚州 ( CA
) 和华盛顿州 ( WA
) 的蛋糕销售情况:
db.cakeSales.insertMany( [ { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"), state: "CA", price: 13, quantity: 120 }, { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"), state: "WA", price: 14, quantity: 140 }, { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"), state: "CA", price: 12, quantity: 145 }, { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"), state: "WA", price: 13, quantity: 104 }, { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"), state: "CA", price: 41, quantity: 162 }, { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"), state: "WA", price: 43, quantity: 134 } ] )
Rank Partitions by an Integer Field
This example uses $rank
in the $setWindowFields
stage to output the quantity
rank of the cake sales for each
state
:
db.cakeSales.aggregate( [ { $setWindowFields: { partitionBy: "$state", sortBy: { quantity: -1 }, output: { rankQuantityForState: { $rank: {} } } } } ] )
在示例中:
partitionBy: "$state"
按state
对集合中的文档分区。
CA
和WA
都有分区。sortBy: { quantity: -1 }
按quantity
以降序 (-1
) 对每个分区中的文档进行排序,因此最高的
quantity
位于最前面。
output
sets therankQuantityForState
field to thequantity
rank using$rank
, as shown in the following results.
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"), "state" : "CA", "price" : 41, "quantity" : 162, "rankQuantityForState" : 1 } { "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"), "state" : "CA", "price" : 12, "quantity" : 145, "rankQuantityForState" : 2 } { "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"), "state" : "CA", "price" : 13, "quantity" : 120, "rankQuantityForState" : 3 } { "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"), "state" : "WA", "price" : 14, "quantity" : 140, "rankQuantityForState" : 1 } { "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"), "state" : "WA", "price" : 43, "quantity" : 134, "rankQuantityForState" : 2 } { "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"), "state" : "WA", "price" : 13, "quantity" : 104, "rankQuantityForState" : 3 }
Rank Partitions by a Date Field
This example shows how to use dates with $rank
in the
$setWindowFields
stage to output the orderDate
rank of
the cake sales for each state
:
db.cakeSales.aggregate( [ { $setWindowFields: { partitionBy: "$state", sortBy: { orderDate: 1 }, output: { rankOrderDateForState: { $rank: {} } } } } ] )
在示例中:
partitionBy: "$state"
按state
对集合中的文档分区。
CA
和WA
都有分区。sortBy: { orderDate: 1 }
按orderDate
升序 (1
) 对每个分区中的文档进行排序,因此最早的
orderDate
位于最前面。
output
sets therankOrderDateForState
field to theorderDate
rank using$rank
, as shown in the following results.
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"), "state" : "CA", "price" : 41, "quantity" : 162, "rankOrderDateForState" : 1 } { "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"), "state" : "CA", "price" : 13, "quantity" : 120, "rankOrderDateForState" : 2 } { "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"), "state" : "CA", "price" : 12, "quantity" : 145, "rankOrderDateForState" : 3 } { "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"), "state" : "WA", "price" : 43, "quantity" : 134, "rankOrderDateForState" : 1 } { "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"), "state" : "WA", "price" : 13, "quantity" : 104, "rankOrderDateForState" : 2 } { "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"), "state" : "WA", "price" : 14, "quantity" : 140, "rankOrderDateForState" : 3 }
Rank Partitions Containing Duplicate Values, Nulls, or Missing Data
创建 cakeSalesWithDuplicates
集合,其中:
蛋糕销售位于加利福尼亚州 (
CA
) 和华盛顿州 (WA
)。文档 6 至 8 与文档 5 具有相同的
quantity
和state
。文档 9 具有与文档 4 相同的
quantity
和state
。文档 10 包含
null
quantity
。文档 11 缺少
quantity
。
db.cakeSalesWithDuplicates.insertMany( [ { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"), state: "CA", price: 13, quantity: 120 }, { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"), state: "WA", price: 14, quantity: 140 }, { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"), state: "CA", price: 12, quantity: 145 }, { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"), state: "WA", price: 13, quantity: 104 }, { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"), state: "CA", price: 41, quantity: 162 }, { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"), state: "WA", price: 43, quantity: 134 }, { _id: 6, type: "strawberry", orderDate: new Date("2020-01-08T06:12:03Z"), state: "WA", price: 41, quantity: 134 }, { _id: 7, type: "strawberry", orderDate: new Date("2020-01-01T06:12:03Z"), state: "WA", price: 34, quantity: 134 }, { _id: 8, type: "strawberry", orderDate: new Date("2020-01-02T06:12:03Z"), state: "WA", price: 40, quantity: 134 }, { _id: 9, type: "strawberry", orderDate: new Date("2020-05-11T16:09:01Z"), state: "CA", price: 39, quantity: 162 }, { _id: 10, type: "strawberry", orderDate: new Date("2020-05-11T16:09:01Z"), state: "CA", price: 39, quantity: null }, { _id: 11, type: "strawberry", orderDate: new Date("2020-05-11T16:09:01Z"), state: "CA", price: 39 } ] )
This example uses $rank
in the $setWindowFields
stage to output the quantity
rank from the
cakeSalesWithDuplicates
collection for each state
:
db.cakeSalesWithDuplicates.aggregate( [ { $setWindowFields: { partitionBy: "$state", sortBy: { quantity: -1 }, output: { rankQuantityForState: { $rank: {} } } } } ] )
在示例中:
partitionBy: "$state"
按state
对集合中的文档分区。
CA
和WA
都有分区。sortBy: { quantity: -1 }
按quantity
以降序 (-1
) 对每个分区中的文档进行排序,因此最高的
quantity
位于最前面。
output
sets therankOrderDateForState
field to thequantity
rank using$rank
。
在以下示例输出中:
Documents with the same
quantity
andstate
have the same rank. If documents have the same rank, there is a gap between that rank and the next rank.包含
null
quantity
的文档以及缺失quantity
的文档在CA
分区的输出中排名最低。这种排序是按照 BSON 比较顺序分配排名的结果,在本示例中,BSON 将null
和缺失值排序在数字值之后。
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"), "state" : "CA", "price" : 41, "quantity" : 162, "rankQuantityForState" : 1 } { "_id" : 9, "type" : "strawberry", "orderDate" : ISODate("2020-05-11T16:09:01Z"), "state" : "CA", "price" : 39, "quantity" : 162, "rankQuantityForState" : 1 } { "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"), "state" : "CA", "price" : 12, "quantity" : 145, "rankQuantityForState" : 3 } { "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"), "state" : "CA", "price" : 13, "quantity" : 120, "rankQuantityForState" : 4 } { "_id" : 10, "type" : "strawberry", "orderDate" : ISODate("2020-05-11T16:09:01Z"), "state" : "CA", "price" : 39, "quantity" : null, "rankQuantityForState" : 5 } { "_id" : 11, "type" : "strawberry", "orderDate" : ISODate("2020-05-11T16:09:01Z"), "state" : "CA", "price" : 39, "rankQuantityForState" : 6 } { "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"), "state" : "WA", "price" : 14, "quantity" : 140, "rankQuantityForState" : 1 } { "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"), "state" : "WA", "price" : 43, "quantity" : 134, "rankQuantityForState" : 2 } { "_id" : 6, "type" : "strawberry", "orderDate" : ISODate("2020-01-08T06:12:03Z"), "state" : "WA", "price" : 41, "quantity" : 134, "rankQuantityForState" : 2 } { "_id" : 7, "type" : "strawberry", "orderDate" : ISODate("2020-01-01T06:12:03Z"), "state" : "WA", "price" : 34, "quantity" : 134, "rankQuantityForState" : 2 } { "_id" : 8, "type" : "strawberry", "orderDate" : ISODate("2020-01-02T06:12:03Z"), "state" : "WA", "price" : 40, "quantity" : 134, "rankQuantityForState" : 2 } { "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"), "state" : "WA", "price" : 13, "quantity" : 104, "rankQuantityForState" : 6 }