英文:
Handling async operation in mongoose virtual property
问题
我在用户模式上创建了一个名为debt的虚拟属性。
debt属性用于返回从Bill模型中的每个用户的总债务的总和聚合。
但虚拟字段debt一直返回Promise {
这是我的代码示例:
userSchema.virtual('debt').get(async function () {
const bills = await this.model('Bill').aggregate([
{
$match: {
$and: [{ 'user._id': this._id }, { balance: { $gt: 0 } }]
}
},
{
$group: { _id: null, total: { $sum: "$balance" } }
}
]);
console.log(bills) // [{_id: null, total: theSummedValue }]
return bills[0].total; // Promise { <pending> }
});
如何返回theSummedValue?
英文:
I created a virtual property on the users schema called debt
the debt property is to return the sum aggregate of each user total debt from the Bill model
But the virtual field debt keeps returning Promise { <pending> }
Here is my code sample:
userSchema.virtual('debt').get(async function () {
const bills = await this.model('Bill').aggregate([
{
$match: {
$and: [{ 'user._id': this._id }, { balance: { $gt: 0 } }]
}
},
{
$group: { _id: null, total: { $sum: "$balance" } }
}
]);
console.log(bills) // [{_id: null, total: theSummedValue }]
return bills[0].total; // Promise { <pending> }
});
how can I return theSummedValue ??
答案1
得分: 1
请查看 issue#1894 和 issue#5762
virtuals 只是获取器/设置器,假定是同步的。
你可以添加一个自定义的 实例方法 代替。
例如("mongoose": "^7.2.1")
import mongoose from 'mongoose';
import { config } from '../../config';
mongoose.set('debug', true);
const userSchema = new mongoose.Schema({
name: String,
});
userSchema.method('dept', async function () {
console.log(this);
// @ts-ignore
const result = await mongoose.model('bill').aggregate([
{
$match: {
$and: [{ 'user._id': this._id }, { balance: { $gt: 0 } }],
},
},
{
$group: { _id: null, total: { $sum: '$balance' } },
},
]);
return result[0].total;
});
const User = mongoose.model('user', userSchema);
const billSchema = new mongoose.Schema({
balance: Number,
user: userSchema,
});
const Bill = mongoose.model('bill', billSchema);
(async function main() {
try {
await mongoose.connect(config.MONGODB_URI);
await Promise.all([User, Bill].map((m) => m.collection.drop()));
// seed
const [user1, user2] = await User.create([{ name: 'Nick' }, { name: 'Jack' }]);
await Bill.create([
{ balance: 100, user: user1 },
{ balance: 200, user: user1 },
{ balance: 0, user: user1 },
{ balance: 50, user: user2 },
]);
//@ts-ignore
const dept = await user1.dept();
console.log("Nick's dept: ", dept);
} catch (error) {
console.error(error);
} finally {
await mongoose.connection.close();
}
})();
输出:
Mongoose: users.drop()
Mongoose: bills.drop()
Mongoose: users.insertOne({ name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, {})
Mongoose: users.insertOne({ name: 'Jack', _id: ObjectId("6498f33d24d77a71b4976084"), __v: 0 }, {})
Mongoose: bills.insertOne({ balance: 100, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b4976087"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 200, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b4976089"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 0, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b497608b"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 50, user: { name: 'Jack', _id: ObjectId("6498f33d24d77a71b4976084"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b497608d"), __v: 0}, {})
{ name: 'Nick', _id: new ObjectId("6498f33d24d77a71b4976083"), __v: 0 }
Mongoose: bills.aggregate([ { '$match': { '$and': [ { 'user._id': new ObjectId("6498f33d24d77a71b4976083") }, { balance: { '$gt': 0 } } ] } }, { '$group': { _id: null, total: { '$sum': '$balance' } } }], {})
Nick's dept: 300
英文:
See issue#1894 and issue#5762
> virtuals are just getters/setters, which are assumed to be synchronous
You can add a custom instance method instead.
E.g.("mongoose": "^7.2.1")
import mongoose from 'mongoose';
import { config } from '../../config';
mongoose.set('debug', true);
const userSchema = new mongoose.Schema({
name: String,
});
userSchema.method('dept', async function () {
console.log(this);
// @ts-ignore
const result = await mongoose.model('bill').aggregate([
{
$match: {
$and: [{ 'user._id': this._id }, { balance: { $gt: 0 } }],
},
},
{
$group: { _id: null, total: { $sum: '$balance' } },
},
]);
return result[0].total;
});
const User = mongoose.model('user', userSchema);
const billSchema = new mongoose.Schema({
balance: Number,
user: userSchema,
});
const Bill = mongoose.model('bill', billSchema);
(async function main() {
try {
await mongoose.connect(config.MONGODB_URI);
await Promise.all([User, Bill].map((m) => m.collection.drop()));
// seed
const [user1, user2] = await User.create([{ name: 'Nick' }, { name: 'Jack' }]);
await Bill.create([
{ balance: 100, user: user1 },
{ balance: 200, user: user1 },
{ balance: 0, user: user1 },
{ balance: 50, user: user2 },
]);
//@ts-ignore
const dept = await user1.dept();
console.log("Nick's dept: ", dept);
} catch (error) {
console.error(error);
} finally {
await mongoose.connection.close();
}
})();
Output:
Mongoose: users.drop()
Mongoose: bills.drop()
Mongoose: users.insertOne({ name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, {})
Mongoose: users.insertOne({ name: 'Jack', _id: ObjectId("6498f33d24d77a71b4976084"), __v: 0 }, {})
Mongoose: bills.insertOne({ balance: 100, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b4976087"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 200, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b4976089"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 0, user: { name: 'Nick', _id: ObjectId("6498f33d24d77a71b4976083"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b497608b"), __v: 0}, {})
Mongoose: bills.insertOne({ balance: 50, user: { name: 'Jack', _id: ObjectId("6498f33d24d77a71b4976084"), __v: 0 }, _id: ObjectId("6498f33d24d77a71b497608d"), __v: 0}, {})
{ name: 'Nick', _id: new ObjectId("6498f33d24d77a71b4976083"), __v: 0 }
Mongoose: bills.aggregate([ { '$match': { '$and': [ { 'user._id': new ObjectId("6498f33d24d77a71b4976083") }, { balance: { '$gt': 0 } } ] } }, { '$group': { _id: null, total: { '$sum': '$balance' } } }], {})
Nick's dept: 300
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论