如何处理猫鼬的循环依赖关系?

时间:2020-07-21 19:14:43

标签: javascript express mongoose mongoose-schema

我的应用程序中包含以下代码

const citySchema = new Schema({
cityName: {
    type: String,
    required: true,
  },
  citizen:[{
      type: Schema.Types.ObjectId,
      ref: "Citizen",
  }],
});
module.exports = mongoose.model("City", citySchema);


const citizenSchema = new Schema({
  citizenName: {
    type: String,
    required: true,
  },
  city:{
      type: Schema.Types.ObjectId,
      ref: "City",
  },
});

module.exports = mongoose.model("Citizen", citizenSchema);

router.post('/', (req, res) => {
      // req.body.cityName
      // req.body.citizenName
})

在我的POST请求中,我同时收到不存在的城市名称(新城市)和公民名称(新公民)。但是我希望这两种架构都能正确更新。

  • 城市应包含公民参考
  • 公民应包含城市参考

我该怎么做?请帮助

1 个答案:

答案 0 :(得分:0)

与之相比,我认为您最好通过数据模型中的预钩中间件应用引用。

代码应如下所示:

const citySchema = new Schema({
cityName: {
    type: String,
    required: true,
  },
  citizen:[{
      type: Schema.Types.ObjectId,
      ref: "Citizen",
  }],
});

// Query middleware to populate the 'citizen' attribute every time the 'find' function is called.
citySchema.pre(/^find/, function (next) {
  this.populate('citizen');
  next();
});

module.exports = mongoose.model("City", citySchema);

const citizenSchema = new Schema({
  citizenName: {
    type: String,
    required: true,
  },
  city:{
      type: Schema.Types.ObjectId,
      ref: "City",
  },
});

citizenSchema.pre(/^find/, function (next) {
  this.populate('city');
  next();
});

module.exports = mongoose.model("Citizen", citizenSchema);

如果您只想选择ID,而不要选择“完整数据”,则可以这样操作:

citizenSchema.pre(/^find/, function (next) {
  this.populate({
    path: 'city',
    select: '_id',
  });
  next();
});

说明:

  • 这样做,每次调用Mongoose的函数,例如findByIdAndUpdatefindfindOne时,引用的数据将出现在citycitizen中属性。实际上,这比每次更新新数据时都更有效。
  • populate方法用于用来自另一个数据模型的数据填充属性。
  • 我插入populate方法中的对象用于获取模型的“名称”(在path中),并选择要从引用的模型中获取哪种数据。在这种情况下,我只想使用_id属性。