javascript - mongoose 虚拟属性在 findById 属性中不起作用
问题描述
我有一个serviceSchema
如下所示:
const serviceSchema = new mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
tags: [
{
type: String,
required: true,
},
],
image: {
type: String,
required: true,
get: (rawImage) => {
return `${config.base_url}/uploads/${rawImage}`;
},
},
},
{
timestamps: true,
toJSON: { getters: true, virtuals: true },
}
);
我已经定义了一个这样的虚拟:
serviceSchema.virtual("avg_satis").get(function () {
Session.find({ service: this._id, status: "conf" }, "satisfaction")
.lean()
.then((sessions) => {
let sum = 0;
sessions.forEach((session) => {
sum += session.satisfaction;
});
console.log(sum / sessions.length);
return sum / sessions.length;
})
.catch((err) => console.log(err));
});
当我执行这样的查询时:
const service = await Service.findById(req.params.service_id).populate(
"user",
"_id name pp"
);
console.log(service.avg_satisf);
虚拟是未定义的。
我也尝试像这样转换虚拟(没有承诺):
serviceSchema.virtual("avg_satis").get(function () {
Session.find({ service: this._id, status: "conf" }, "satisfaction")
.lean()
.exec((err, sessions) => {
if (err) {
console.log(err);
}
let sum = 0;
sessions.forEach((session) => {
sum += session.satisfaction;
});
console.log(sum / sessions.length);
return sum / sessions.length;
});
});
解决方案
虚拟字段在数据库中并不真实存在。它是一种速记,所以你不能查询它。你想要的是 call populate
,请阅读 doc 并使用它。
如果你真的想在虚拟中得到一个承诺
serviceSchema.virtual("avg_satis").get(function () {
// return promise to caller
return Session.find({ service: this._id, status: "conf" }, "satisfaction")
.lean()
.then((sessions) => {
let sum = 0;
sessions.forEach((session) => {
sum += session.satisfaction;
});
console.log(sum / sessions.length);
return sum / sessions.length;
})
.catch((err) => console.log(err));
});
// outside
await service.avg
文档中还有另一种方式,例如静态或方法
- - 更新
它已经在猫鼬文档中了
// define a schema
const animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
return mongoose.model('Animal').find({ type: this.type }, cb);
};
所以
// define a schema
serviceSchema.methods.caleAvg = async function() {
return Session.find({ service: this._id, status: "conf" }, "satisfaction")
.lean()
.then((sessions) => {
let sum = 0;
sessions.forEach((session) => {
sum += session.satisfaction;
});
console.log(sum / sessions.length);
return sum / sessions.length;
}).catch((err) => console.log(err));
};
// outside caller
const avg = await service.caleAvg()
如果您想这样做并将其附加到 mongooDB 中的响应中,您需要研究他们的aggregate
管道。
推荐阅读
- vue.js - Vue没有从API中找到图像路径
- c# - Serilog PostgresSql 接收器中的 .NET Core 自定义列
- arduino - 如何从 RFID 卡读取数据,然后通过串行监视器用新数据覆盖它?
- database - 如何在单独的函数中连接到 MongoDB?
- excel - 四舍五入给定的数字
- bash - 如何在bash中使用sed命令替换字符串中的特殊字符
- java - 使用 Selenium/java 将网页保存为 PDF
- reactjs - 反应数组状态不推送值
- jupyter-lab - 无法通过 JupyterLab 中的“从路径打开”打开文件
- c++ - 如何控制过滤器尺寸