MongoDB聚合运算符:$rank
$rank
聚合运算符返回$setWindowFields
阶段分区内文档相对排名位置,文档排名先后顺序有$setWindowFields
阶段的sortBy
字段决定,sortBy
只能取一个字段值。另外,如果多个文档有相同的排名,$rank
会将文档与后续值放在排名的空隙中。
语法
{
$rank: {
} }
$rank
不接受任何参数。
使用
$rank
和$denseRank
的不同之处在于它们对sortBy
字段重复值的处理不同,例如,sortField的值有7、9、9、10:
$denseRank
排名的值为1、2、2、3,重复值9的排名为2,而10的排名为3,没有排名间隙。$rank
排名的值为1、2、2、4,重复值9的排名为为2,但10的排名为4,这里存在一个间隙3。
对于文档的sortBy
字段值为空或缺失的情况,sortBy
字段相关的排名按照BSON比较顺序执行。
举例
使用下面的脚本创建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 }
] )
用整型字段进行分区排名
下面的聚合操作在$setWindowFields
阶段使用$rank
输出每个州的蛋糕销售量quantity
排名:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: {
quantity: -1 },
output: {
rankQuantityForState: {
$rank: {
}
}
}
}
}
] )
在本例中:
partitionBy: "$state"
根据state
对集合中的文档进行分区,分为两个区CA
和WA
。sortBy: {quantity: -1 }
根据quantity
对分区内的文档由大到小进行排序,销量最高的quantity
排在最前面。output
使用$rank
将rankQuantityForState
字段设置为quantity
排名。
操作返回下面的结果:
{
"_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "rankQuantityForState" : 1 }
{
"_id" : 2, "type" :