我在 nextjs 应用程序中使用猫鼬,并且在特定情况下填充方法有问题。 让我用下面的代码解释一下:
这是我的代码: 第一个模型
import mongoose, { Schema } from "mongoose";
const muscleSchema = new Schema(
{
name: {
type: String,
required: [true, "Name is required"],
trim: true,
enum: ['legs', 'glutes', 'back', 'abs', 'pectorals', 'arms', 'shoulders'],
},
}
);
const Muscle = mongoose.models.Muscle || mongoose.model("Muscle", muscleSchema)
export default Muscle;
第二型号:
import mongoose, { Schema } from "mongoose";
const exerciseSchema = new Schema(
{
name: {
type: String,
required: [true, "Name is required"],
trim: true,
},
muscle: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Muscle',
required: true,
}
}
);
const Exercise = mongoose.models.Exercise || mongoose.model("Exercise", exerciseSchema)
export default Exercise;
这是我获得 ONE Exercice 的“exercise”路线 api :
export async function GET(request, { params }) {
try {
const { id } = params;
await connectDb();
const exercise = await Exercise.findById(id);
await exercise.populate({ path: "muscle", select: "name" });
console.log(exercise)
return NextResponse.json(exercise, { status: 200 });
} catch (err) {
const { errors } = err;
return NextResponse.json(errors, { status: 404 });
}
}
它工作得很好,我明白了:
{
"_id": "6559e924d02b9f36fd7f574d",
"name": "squats",
"muscle": {
"_id": "65101d9667cb93cb766bfe79",
"name": "legs"
},
"__v": 0
}
但是当我想通过这条路线通过肌肉ID进行一些练习时,填充dosen似乎不起作用:
export async function GET(request, { params }) {
try {
const muscle_id = request?.url.split("=")[1];
await connectDb();
const findExercises = async () => {
if (muscle_id) {
console.log(muscle_id);
return Exercise.find({ muscle: muscle_id });
}
return Exercise.find();
};
console.log("before", await findExercises());
const exercises = await findExercises();
exercises.map(async (exercice) => {
return await exercice.populate({
path: "muscle",
select: "name",
});
});
console.log("after", exercises);
return NextResponse.json(exercises, { status: 200 });
} catch (err) {
const { errors } = err;
return NextResponse.json(errors, { status: 404 });
}
}
这是我的回应:
[
{
"_id": "6559e924d02b9f36fd7f574d",
"name": "squats",
"muscle": "65101d9667cb93cb766bfe79",
"__v": 0
},
{
"_id": "6559f1f2d02b9f36fd7f57ab",
"name": "deadlift",
"muscle": "65101d9667cb93cb766bfe79",
"__v": 0
}
]
但我应该有类似的东西:
[
{
"_id": "6559e924d02b9f36fd7f574d",
"name": "squats",
"muscle": {
"_id": "65101d9667cb93cb766bfe79",
"name": "legs"
},
"__v": 0
},
{
"_id": "6559f1f2d02b9f36fd7f57ab",
"name": "deadlift",
"muscle": {
"_id": "65101d9667cb93cb766bfe79",
"name": "legs"
},
"__v": 0
}
]
有人可以帮助我吗?
我不太确定您为什么创建函数
findExercises()
来检查 muscle_id
。您可以在正常控制流中执行此操作,并根据if
的条件结果确定查询对象。
您的
map
函数也没有执行您期望的操作,想象一下,如果您的 find
结果返回数十万甚至数百万个文档(这发生在生产环境中),那么您将为每个文档执行一次数据库请求在那张地图里。如果这是一条每分钟接收数百或数千个请求的繁忙路线,您的应用程序将承受巨大的压力。
无论如何,
Model.find()
方法可以采用空查询对象,因此实现这些更改,希望您能得到所需的结果:
try {
const muscle_id = request?.url.split("=")[1];
await connectDb();
// If muscle_id truthy then create query on muscle property
// else create empty query
const query = muscle_id ? { muscle: muscle_id } : {};
const exercises = await Exercise.find(query).populate({
path: "muscle",
select: "name"
});
return NextResponse.json(exercises, { status: 200 });
} catch (err) {
const { errors } = err;
return NextResponse.json(errors, { status: 404 });
}