我在用户模式上创建了一个名为debt的虚拟属性

debt属性将返回Bill model中每个用户总债务的总和

但是虚拟字段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> }
});

我如何退还Summed Value??

推荐答案

issue#1894issue#5762

虚拟只是getter/setter,它们被认为是同步的

您可以改为添加自定义instance method.

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();
    }
})();

输出:

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

Node.js相关问答推荐

如何在Node.js 中设置图表js的背景色

用于SLACK命令返回json而不是文本的AWS lambda函数

MongoDB:通过匹配输入字符串或输入字符串中的单个单词进行搜索

仅在 vue 脚本未退出的情况下使用 docker 时出现错误

Typescript 正则表达式:过滤器返回空

MongoDB - 查找查询以判断是否存在少量字段,结合字段上的 AND

如何从动态Typescript 文件加载模块

带有事件网格的 Azure 函数在没有 ngrok 的情况下在本地运行

使用 Node.js 在 MongoDB 中搜索

在express js模型中将js转换为Typescript 时Typescript 错误

配额超出了每分钟的 Sheets API 写入请求数. node .js

如何在 TypeScript 中输出 Hackerrank 二叉树问题?

NodeJs 过滤掉目录异步

Web3.js 脚本在监听 CreatedPairs 时退出

使用 WebSockets 有服务器成本吗?

使 pm2 登录到控制台

使用 Webpack 和 font-face 加载字体

如何使用 Node.js、Express 和 Mongoose 进行身份验证?

Fluxible 中的脱水和再水合代表什么?

NPM:为什么要安装这个包?