更新引用另一个模型而不重复的属性

时间:2016-10-13 12:53:05

标签: javascript mongodb mongoose

我正在尝试创建一个事件列表,用户可以在其中添加和删除自己的事件,并指定他们是否将访客带入该事件。

所以我有一个事件架构和一个用户架构,其中事件架构引用了用户架构。因此,当创建新事件时,用户可以使用其ID将自己添加到该事件。

现在我正在努力使用户也可以包含访客。我如何实现这一目标?

以下是一个示例

用户架构:

let UserSchema = new mongoose.Schema({
  email: {
    type: String,
    lowercase: true,
    unique: true,
    required: true
  },
    name:{
    type: String,
    require: true
  },
  password: {
    type: String,
    required: true
  },
...

事件架构:

let EventSchema = new mongoose.Schema({
  date: {
    type: Date,
    unique: true,
    timestamps: true,
    required: true
  },
  title: {
    type: String,
    require: true
  },
// Guest property is ignored
  attending: [{
    type: mongoose.Schema.Types.ObjectId,
    guest: Number, //This is being ingored and never updated 
    ref: 'User'
    }]
})

在模式中定义相关部分的第二种方式:

...
//In this example the guest will be added but duplicates will occur
  user:[{
    guest: Number, // To make it clear this is not referencing anything it's just a number
    attending: {
      type: mongoose.Schema.Types.ObjectId, 
      ref: 'User'
      }
}]

如何在上述配置中使用addToSet更新类型和来宾属性(以防止重复)?

Event.findOneAndUpdate({_id:req.body.eventId}, query) 

1 个答案:

答案 0 :(得分:1)

我不认为您了解mongoose模式的工作原理,您可能希望在文档上花费更多时间。

你提供的代码是你的Schema中一个名为Events的字段,它是一个对象数组,每个对象都有一个名为attending的字段,它本身就是必须是ObjectId类型并引用' User'采集。字段定义中还有一个guest属性,Mongoose将忽略该属性,因为它不了解您要求的内容。

了解这个数据结构是Mongoose如何验证和保存数据的说明。它通常不会在运行时为大多数应用程序更新,也不会直接存储数据,其目的是为Mongoose提供有关如何存储数据的线索。

/ **根据评论和更新的问题进行编辑** /

正如我之前所说,你不能直接将另一个字段嵌入到字段的定义中。您可以做的是创建一个混合类型,其中包含两条信息,但这需要您在某种程度上自己管理事物。

let EventSchema = new mongoose.Schema({
  date: {
    type: Date,
    unique: true,
    timestamps: true,
    required: true
  },
  title: {
    type: String,
    require: true
  },

  attendees: [{
    user : {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    guests : Number
  }]
})

无论何时将任何人添加到参加者列表中,您都需要调用event.markModified()以确保它被保存。如果您不想允许重复用户,则还需要进行检查。确保发生这种情况的一种方法是在获取事件时populate()该字段,然后在本地检查匹配项。

/ **编辑#2 ** /

您还可以明确创建另一个架构来“保持”#39;您的用户和#Guests信息,然后将创建Mongoose将要观看的模型,您可以通过正常的Mongoose方法对它们应用验证,而不用担心脏检查。这看起来像这样:

// in ./models/attendee.js
let AttendeeSchema = new Schema({
    user : {
      type: mongoose.Schema.Types.ObjectId, 
      ref: 'User',
      unique : true 
      },
    guests : Number
}

mongoose.model('Attendee', AttendeeSchema);

// in your Events definition
    let Attendee    = mongoose.model('Attendee');
    let EventSchema = new mongoose.Schema({
      date: {
        type: Date,
        unique: true,
        timestamps: true,
        required: true
      },
      title: {
        type: String,
        require: true
      },
      attendees: [Attendee]
    })

/ **编辑3:现在,查询** /

在给定现有事件和已知用户的情况下插入新与会者:

event.attendees.push(new Attendee({user: user, guests: 5}));
event.save(console.log);

要更新现有与会者,您需要先找到您正在寻找的人:

let attendee = event.attendees.find((attendee) => { return attendee._id.toString() === user._id.toString(); }); 
attendee.guests = 10;
event.save(console.log);