乐闻世界logo
搜索文章和话题

How to get item ranking in list sorted by multiple fields in Mongoose

4 个月前提问
3 个月前修改
浏览次数42

1个答案

1

在 Mongoose 中,如果您想要获取按多个字段排序的列表中的项目排名,您可以使用 MongoDB 的聚合管道(Aggregation Pipeline)来实现这一功能。以下是具体的步骤和示例:

步骤 1: 定义数据模型

首先,假设我们有一个 User 模型,包含 scoreage 两个字段,我们想根据这两个字段来进行排序。

javascript
const mongoose = require('mongoose'); const { Schema } = mongoose; const userSchema = new Schema({ name: String, score: Number, age: Number }); const User = mongoose.model('User', userSchema);

步骤 2: 使用聚合管道排序并添加排名

使用 MongoDB 的 $sort 来排序,并使用 $group$push 来生成带有排名的列表。

javascript
User.aggregate([ // 首先按照需要的字段进行排序 { $sort: { score: -1, age: 1 } }, // 按 score 降序,age 升序排序 // 将排序后的数据添加到一个新的数组,并为每个元素添加排名 { $group: { _id: null, // 不按任何字段分组,也就是说整个集合作为一组 users: { $push: "$$ROOT" } // 将所有文档添加到 users 数组 } }, { $unwind: { path: "$users", includeArrayIndex: "rank" // includeArrayIndex 会给每个元素添加一个新字段,表示其在数组中的索引,即排名 } }, { $replaceRoot: { newRoot: { $mergeObjects: ["$users", { rank: { $add: ["$rank", 1] } }] // 将 rank 索引转换为从1开始的排名 } } } ]).exec((err, results) => { if (err) throw err; console.log(results); // 打印带有排名的用户列表 });

解释:

  1. 排序: 使用 $sort 根据 score 降序和 age 升序对用户进行排序。
  2. 组合: 使用 $group 将所有文档推到一个数组中,这步不分组。
  3. 解包: 使用 $unwind 将数组解包,并通过 includeArrayIndex 为每个元素添加索引作为排名。
  4. 重新构造文档: 使用 $replaceRoot$mergeObjects 将原始文档和新增的 rank 字段合并,修正排名使其从1开始。

这个聚合管道不仅能对数据进行排序,还能够有效地为每条记录添加一个表示其在排序后列表中的排名的字段。这在实现如排行榜这类功能时非常有用。

2024年6月29日 12:07 回复

你的答案