猫鼬一对多的关系问题

时间:2020-04-27 06:40:31

标签: javascript mongodb express mongoose

我有一个用户模型和一个汽车模型。一个用户可以拥有多辆汽车。这是代码-

let UserSchema = new Schema({
    name:String,
    age:String,
    cars:[{
        type:Schema.Types.ObjectId,
        ref:"Car"
    }]
})

const User = mongoose.model("User",UserSchema)

let CarSchema = new Schema({
    make:String,
    model:String,
    owner:{
        type:Schema.Types.ObjectId,
        ref:"User"
    }
})

const Car = mongoose.model("Car",CarSchema)

我正在创建用户和汽车模型,并将用户ID存储在汽车中,反之亦然-

const user = new User({
    _id: new mongoose.Types.ObjectId(),
    name:'Raj',
    age:50
})

user.save(function(err){
    if(err){
        console.log(err)
    }
    const car1 = new Car({
        make:'Toyota',
        model:'568',
        owner:user._id
    })
    car1.save(function(err){
        if(err){
            console.log(err)
        }
    }) 
    user.cars.push(car1)
    user.save()
})

这是可行的,但是如果我需要对一个Car模型执行操作,那么它显然不会反映在用户car阵列上,因此我必须单独进行操作,即模型没有“实际”链接。我该如何做,以便在Car模型上执行诸如delete之类的操作,会自动将其从用户car阵列中删除。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

在拆卸汽车时,没有自动方法从用户删除汽车。 因此,您需要对两个文档进行操作。

但是只有父引用是一种更简单的方法。不要在用户模型中保留汽车参考,并使用virtual populate填充用户的汽车。

以下是步骤:

1-)更改用户架构以设置虚拟填充:

var mongoose = require("mongoose");
var Schema = mongoose.Schema;

let UserSchema = new Schema(
  {
    name: String,
    age: Number,
  },
  {
    toJSON: { virtuals: true },
  }
);

UserSchema.virtual("cars", {
  ref: "Car",
  localField: "_id",
  foreignField: "owner",
});

const User = mongoose.model("User", UserSchema);

请注意,我删除了汽车字段,在架构中添加了toJSON: { virtuals: true }选项,设置了虚拟的。 (也将年龄类型修改为数字)。

2-)现在,我们可以像这样创建用户和汽车:

router.post("/users", async (req, res) => {
  const user = new User({ name: "Raj", age: 50 });

  try {
    await user.save();

    const car1 = new Car({
      make: "Toyota",
      model: "568",
      owner: user._id,
    });

    await car1.save();

    res.send("User and car saved");
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});

如您所见,由于不需要将汽车推入用户的汽车并保存,因此我们需要2 db操作而不是3 db操作。

3-)现在,我们可以使用填充向用户填充汽车:

router.get("/users/:id", async (req, res) => {
  try {
    const user = await User.findById(req.params.id).populate("cars");

    res.send(user);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
});

这将给出输出:

{
    "_id": "5ea685a3f1a0b02db8aaffe2",
    "name": "Raj",
    "age": 50,
    "__v": 0,
    "cars": [
        {
            "_id": "5ea685a5f1a0b02db8aaffe3",
            "make": "Toyota",
            "model": "568",
            "owner": "5ea685a3f1a0b02db8aaffe2",
            "__v": 0
        }
    ],
    "id": "5ea685a3f1a0b02db8aaffe2"
}