查询以获取最新的三个用户,按日期排序 - Mongoose Node.js
Query to get latest three users, sort by date - Mongoose Node.js
这是来自Mongodb的数据
(Task.json)
{
"username": "john",
"taskId": "001",
"date": "2020-02-18T20:14:19.000Z",
},
{
"username": "david",
"taskId": "001",
"date": "2020-02-18T21:48:19.000Z",
},
{
"username": "john",
"taskId": "002",
"date": "2020-02-15T20:20:32.000Z",
}
... many more
我想要达到的目标
- 我正在尝试编写一个 returns
taskId
的查询,其中包含
最近 users
执行任务的人(按 date
- 降序排列)。
- 我只希望最后三个执行任务的用户显示在列表中,因此
user
数组不应包含更多每个任务的 3 个用户
这是我创建的一个示例,说明我希望如何响应:
{
"tasks": [
{
"taskid": "001",
"users": [
{
"username": "david",
"date": "2020-02-18T21:48:19.000Z"
},
{
"username": "john",
"date": "2020-02-18T20:14:19.000Z"
}
]
},
{
"taskid": "002",
"users": [
{
"username": "john",
"date": "2020-02-15T20:20:32.000Z"
}
]
}
]
}
我目前的进度:
router.route("/latest-tasks").get((req, res) => {
Task.find()
.sort({ date: "desc" })
.then(doc =>
res.status(200).json({
taskId: doc.taskId,
list: doc.map(doc => {
return {
username: doc.username,
date: doc.date
};
})
})
)
.catch(err => res.status(400).json("Error: " + err));
});
这里有点多查询的场景,建议使用MongoDB聚合来实现。此查询应该有效:
Todo.aggregate([
{
$sort: { taskId: 1, date: 1 }
},
{
$group: {
_id: "$taskId",
users: {
$push: { username: "$username", date: "$date" }
}
}
},
{
$project: {
_id: 0,
taskid: "$_id",
users: {
$filter: {
input: [
{ $arrayElemAt: ["$users", 0] },
{ $arrayElemAt: ["$users", 1] },
{ $arrayElemAt: ["$users", 2] }
],
as: "user",
cond: { $ne: ["$$user", null] }
}
},
}
}
]).exec()
.then(doc => { console.log(doc); })
.catch(err => { console.log(err); });
聚合管道说明:
$sort
:这使用 taskId 和 date 字段按升序对任务进行排序
$group
:按 taskId 对任务进行分组。这就是我们如何让所有用户与任务相关联
$project
:这有助于仅提取与任务关联的前 3 个用户。此管道阶段中使用的 $filter
运算符有助于删除空值,以防任务最多没有三个用户与之关联。
链接:Aggregation Pipeline, Pipeline Stages, Pipeline Operators
您需要使用.aggregate
:
猫鼬代码未测试
Task.aggregate([
{
$sort: {
taskId: 1,
date: -1
}
},
{
$group: {
_id: "$taskId",
users: {
$push: {
username: "$username",
date: "$date"
}
}
}
},
{
$facet: {
tasks: [
{
$sort: {
_id: 1
}
},
{
$project: {
_id: 0,
taskid: "$_id",
users: 1
}
}
]
}
}
]).exec()
.then( doc => res.status(200).json(doc))
.catch(err => res.status(400).json("Error: " + err));
这是来自Mongodb的数据 (Task.json)
{
"username": "john",
"taskId": "001",
"date": "2020-02-18T20:14:19.000Z",
},
{
"username": "david",
"taskId": "001",
"date": "2020-02-18T21:48:19.000Z",
},
{
"username": "john",
"taskId": "002",
"date": "2020-02-15T20:20:32.000Z",
}
... many more
我想要达到的目标
- 我正在尝试编写一个 returns
taskId
的查询,其中包含 最近users
执行任务的人(按date
- 降序排列)。 - 我只希望最后三个执行任务的用户显示在列表中,因此
user
数组不应包含更多每个任务的 3 个用户
这是我创建的一个示例,说明我希望如何响应:
{
"tasks": [
{
"taskid": "001",
"users": [
{
"username": "david",
"date": "2020-02-18T21:48:19.000Z"
},
{
"username": "john",
"date": "2020-02-18T20:14:19.000Z"
}
]
},
{
"taskid": "002",
"users": [
{
"username": "john",
"date": "2020-02-15T20:20:32.000Z"
}
]
}
]
}
我目前的进度:
router.route("/latest-tasks").get((req, res) => {
Task.find()
.sort({ date: "desc" })
.then(doc =>
res.status(200).json({
taskId: doc.taskId,
list: doc.map(doc => {
return {
username: doc.username,
date: doc.date
};
})
})
)
.catch(err => res.status(400).json("Error: " + err));
});
这里有点多查询的场景,建议使用MongoDB聚合来实现。此查询应该有效:
Todo.aggregate([
{
$sort: { taskId: 1, date: 1 }
},
{
$group: {
_id: "$taskId",
users: {
$push: { username: "$username", date: "$date" }
}
}
},
{
$project: {
_id: 0,
taskid: "$_id",
users: {
$filter: {
input: [
{ $arrayElemAt: ["$users", 0] },
{ $arrayElemAt: ["$users", 1] },
{ $arrayElemAt: ["$users", 2] }
],
as: "user",
cond: { $ne: ["$$user", null] }
}
},
}
}
]).exec()
.then(doc => { console.log(doc); })
.catch(err => { console.log(err); });
聚合管道说明:
$sort
:这使用 taskId 和 date 字段按升序对任务进行排序$group
:按 taskId 对任务进行分组。这就是我们如何让所有用户与任务相关联$project
:这有助于仅提取与任务关联的前 3 个用户。此管道阶段中使用的$filter
运算符有助于删除空值,以防任务最多没有三个用户与之关联。
链接:Aggregation Pipeline, Pipeline Stages, Pipeline Operators
您需要使用.aggregate
:
猫鼬代码未测试
Task.aggregate([
{
$sort: {
taskId: 1,
date: -1
}
},
{
$group: {
_id: "$taskId",
users: {
$push: {
username: "$username",
date: "$date"
}
}
}
},
{
$facet: {
tasks: [
{
$sort: {
_id: 1
}
},
{
$project: {
_id: 0,
taskid: "$_id",
users: 1
}
}
]
}
}
]).exec()
.then( doc => res.status(200).json(doc))
.catch(err => res.status(400).json("Error: " + err));