我有两个集合,一个是优惠券,另一个是用户。因此,在我的应用程序中,我想根据用户电子邮件分配优惠券。现在,在我的优惠券集合中,我想存储用户信息(来自用户集合)以及我们刚刚在优惠券集合中保存的电子邮件。因此,在通过输入电子邮件 ID 创建优惠券时,我希望在用户集合中获取具有相同 email_id 的用户,并将其与我刚刚在优惠券集合中创建的优惠券一起保存。
下面是我正在做的事情,我使用的是 populate 方法,但我将 Users 集合中的 _id 保存到优惠券集合中,并且工作正常,直到需求发生变化,现在我想用 user_email 保存它。
用户收藏:
const mongoose = require("mongoose");
const hasher = require("wordpress-hash-node");
const userSchema = new mongoose.Schema(
{
id: {
type: String,
unique: true,
},
first_name: {
type: String,
required: true,
trim: true,
min: 3,
max: 25,
},
last_name: {
type: String,
required: true,
trim: true,
min: 3,
max: 25,
},
user_email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
},
user_pass: {
type: String,
required: true,
},
role: {
type: String,
enum: [
"customer",
"admin",
"accountant sr",
"accountant jr",
"shipping sr",
"shipping jr",
],
default: "customer",
},
billing_phone: {
type: String,
required: true,
},
birth_date: {
type: String,
required: true,
},
userVerified: {
type: Boolean,
},
disable: {
type: Boolean,
},
document: [
{
url: { type: String },
},
],
documentVerified :{
verified:{type:Boolean},
status:{type:String}
},
billingAddress: {
companyName: {
type: String,
},
streetAddress: {
type: String,
},
city: {
type: String,
},
province: {
type: String,
},
postalCode: {
type: String,
},
country:{
type:String
}
},
// wishlist:[{
// productID: {type:mongoose.Schema.Types.ObjectId, ref:'Products'}
// }]
},
{ timestamps: true }
);
userSchema.virtual("password").set(function (password) {
this.user_pass = hasher.HashPassword(password);
});
userSchema.methods = {
authenticate: function (password) {
return hasher.CheckPassword(password, this.user_pass);
},
};
userSchema.virtual("full_name").get(function () {
return `${this.first_name} ${this.last_name}`;
});
module.exports = mongoose.model("User", userSchema);
优惠券领取:
const mongoose = require("mongoose");
const couponSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
email: {
type: String,
required: true,
},
couponCode: {
type: String,
required: true,
unique: true,
},
amount: {
type: Number,
required: true,
},
expireDate: {
type: String,
required: true,
default: "",
},
isActive: {
type: Boolean,
required: true,
default: true,
},
});
const Coupon = mongoose.model("Coupon", couponSchema);
module.exports = Coupon;
保存优惠券的控制器
const createCoupon = async (req, res) => {
const { user, email, amount, expireDate, isActive } = req.body;
function couponGenerator() {
var coupon = "";
var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 6; i++) {
coupon += possible.charAt(Math.floor(Math.random() * possible.length));
}
return coupon.toUpperCase();
}
const couponCode = couponGenerator();
try {
const newCoupon = new Coupon({
user: mongoose.Types.ObjectId(user),
email,
couponCode,
amount,
expireDate,
isActive,
});
await newCoupon.save(function (err) {
if (err) {
res.json({
status: "ERROR",
error: err,
});
}
});
res.json({
status: "SUCCESS",
Coupon: newCoupon,
});
} catch (error) {
throw new Error(error);
}
};
结果:
如果我在创建优惠券时从用户集合中保存_id,并且它会在创建的优惠券中生成用户信息,那么我的上述方法可以正常工作。但我需要一种方法,可以在优惠券模型中使用电子邮件并获取具有(来自用户)user_email = email(来自优惠券)的用户信息。
您可以使用简单的
Model.aggregate()
来完成此操作,在 $lookup
集合中执行 users
并将 Coupon.email
与 User.user_email
进行匹配。接下来是可选的 $unwind
来获取对象,因为 $lookup
返回一个数组。
一个例子是:
const coupons = await Coupon.aggregate([
{
$lookup: {
"from": "users",
"localField": "email",
"foreignField": "user_email",
"as": "user_details"
}
},
{
$unwind: "$user_details"
}
]);
请参阅此处了解工作示例。