如何在预中间件中实现 mongo 聚合管道?



我有两个模式 - 产品和订单 - 每个订单都包含 object.id 引用的产品数组。我正在尝试做的是在保存新订单文档之前$sum数组中的 product.sellPrice 并设置 totalSale。

const orderSchema = new mongoose.Schema({
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Product"
}
],
totalSale: {
type: Number,
min: 0
}
});

const productSchema = new mongoose.Schema({
name: {
type: String,
unique: true,
required: true
},
sellPrice: {
type: Number,
min: 0,
required: true
}}):

因此,每个订单将包含一系列产品。所以尝试做的是在 orderSchema.pre('save'( 钩子中,我尝试运行如下聚合:

orderSchema.pre("save", function(next) {
let order = this;
order.totalSale = order.aggregate([
{ $unwind: { path: "$products" } },
{ $group: { _id: null, $sum: {} } }
]);

这甚至可能吗,或者是否有更好的方法来汇总订单中每种产品的价格。它实际上不必是pre("保存"(

首先,是的,可以在pre中使用聚合函数。

如果要使用它,则需要在聚合管道中添加$lookup,以将产品数据填充到订单中。

在产品上使用find()怎么样?

const Product = mongoose.model('Product');
OrderSchema.pre('save', function (next) {
let order = this;
// if products array is empty, skip the process
if (!this.products || !Array.isArray(this.products) || !this.products.length < 1) {
return next();
}
Product.find({ $in: this.products }, { sellPrice: 1 })
.lean()
.exec(function (err, products) {
let totalSale = 0;
if (Array.isArray(products)) {
products.forEach(product => {
totalSale += product.sellPrice;
});
}
order.totalSale = totalSale;
next(err);
});
});
orderSchema.pre("save", function(next) {
let order = this;
let temp = order.products.map(product => {
return { _id: mongoose.Types.ObjectId(product) };
});
let totalSale = 0;
let promises = Product.find({ _id: { $in: temp } }).exec();
promises
.then(data => {
data.forEach(product => {
totalSale += product.sellPrice;
});
order.totalSale = totalSale;
next();
})
.catch(err => {
console.error(err);
});
});

由于 find 返回所有符合条件的条件,因此我将它们保存在一个变量中,然后迭代它们。

最新更新