根据 MongoDb 中的字段值将数据从一个集合保存到另一个集合

问题描述 投票:0回答:1

我有两个集合,一个是优惠券,另一个是用户。因此,在我的应用程序中,我想根据用户电子邮件分配优惠券。现在,在我的优惠券集合中,我想存储用户信息(来自用户集合)以及我们刚刚在优惠券集合中保存的电子邮件。因此,在通过输入电子邮件 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(来自优惠券)的用户信息。

javascript node.js mongodb mongoose aggregation-framework
1个回答
0
投票

您可以使用简单的

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"
  }
]);

请参阅此处了解工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.