我正在使用 nodejs/express 和 mongoose 开发端点。端点应该只返回找到的 ID,如下所示:
{
"id": 3000,
"group": 3,
"title": "",
"start_time": "2023-07-31T11:00:00.000Z",
"end_time": "2023-07-31T20:00:00.000Z",
"category": "green"
}
但是,当我测试(localhost:3000 / api / one / 3000)时,它返回属于用户的所有值,而不是仅一个:
{
"_id": "658",
"schedule": [
{
"events": [
{
"id": 3000,
"group": 3,
"title": "",
"start_time": "2023-12-01T11:00:00.000Z",
"end_time": "2023-12-01T20:00:00.000Z",
"category": "green",
},
{
"id": 3001,
"group": 3,
"title": "",
"start_time": "2023-12-02T11:00:00.000Z",
"end_time": "2023-12-02T20:00:00.000Z",
"category": "green",
},
{
"id": 3002,
"group": 3,
"title": "",
"start_time": "2023-12-03T11:00:00.000Z",
"end_time": "2023-12-03T20:00:00.000Z",
"category": "green",
},
{
"id": 3003,
"group": 3,
"title": "",
"start_time": "2023-12-04T11:00:00.000Z",
"end_time": "2023-12-04T20:00:00.000Z",
"category": "green",
},
{
"id": 3004,
"group": 3,
"title": "",
"start_time": "2023-12-07T11:00:00.000Z",
"end_time": "2023-12-07T20:00:00.000Z",
"category": "green",
}
]
}
]
}
这是 mongo 模式:
import mongoose, { model, Schema } from "mongoose";
const eventSchema = new mongoose.Schema({
id: Number,
group: Number,
title: String,
start_time: Date,
end_time: Date,
category: String,
});
const individualSchema = new mongoose.Schema({
name: String,
events: [eventSchema],
});
const ScheduleSchema = new mongoose.Schema({
schedule: [individualSchema],
});
export default model("Schedule", ScheduleSchema);
这是我认为 findOne() 上缺少的功能:
export const getById = async (req, res) => {
try {
const id = req.params.id;
const found = await ScheduleSchema.findOne(
{ "schedule.events.id": id },
{ "schedule.events.$": 1 }
);
res.json(found);
} catch (error) {
console.log(error);
console.error(error);
}
};
我该如何修复它,使其只返回给定的 id?
我认为根据您的文档设计,最好的方法是通过使用聚合并使用生成的对象来模拟
findOne
,如下所示:
export const getById = async (req, res) => {
try {
const id = req.params.id;
const agg = await ScheduleModel.aggregate([
{
$match: {
"schedule.events.id": id
}
},
{
$unwind: "$schedule"
},
{
$unwind: "$schedule.events"
},
{
$match: {
"schedule.events.id": id
}
},
{
$replaceRoot: {
newRoot: "$schedule.events"
}
}
]);
const found = agg[0]; //< Use the 0 indexed object since aggregate returns an array.
res.json(found);
} catch (error) {
console.log(error);
console.error(error);
}
};
请参阅此处了解聚合的工作示例。
注意:为了清楚起见,我使用
ScheduleModel
作为模型的名称来执行查询。将模型命名为 ScheduleSchema
可能会让将来使用此答案的初学者感到困惑。
您可能喜欢这样的聚合功能:
db.collection.aggregate([
{
"$match": {
"schedule.events.id": 3000
}
},
{
"$project": {
"schedule": {
"$map": {
"input": "$schedule",
"as": "s",
"in": {
"events": {
"$filter": {
"input": "$$s.events",
"as": "e",
"cond": {
"$eq": [
"$$e.id",
3000
]
}
}
}
}
}
}
}
},
{
"$replaceRoot": {
"newRoot": {
$mergeObjects: "$schedule"
}
}
},
{
"$replaceRoot": {
"newRoot": {
$mergeObjects: "$events"
}
}
}
])
解释: