How do a create an array subdocument that references "guests" from another model at a future date?

huangapple go评论74阅读模式
英文:

How do a create an array subdocument that references "guests" from another model at a future date?

问题

我有一个名为"events"的模型,其中"guests"可以"signup"并加入活动。每个事件都是一个比赛,因此每个活动都有一个最大数量的"guests",因为某些位置被标记为"winners"。为了确保在访客报名时不会分配过多的奖品,我想在创建活动时预先构建嵌套的"guests"数组。

然而,在这样做时,我收到了类型转换错误"Cast to ObjectId failed for value '{}' (type Object) at path 'guests'",因为我还没有为每个访客分配对象ID...

这是设计如此,因为占位符是用"winner"或"loser"状态构建的,以便访客在注册并被分配到数组中时可以立即收到通知。

有没有办法让我的"events"模型引用"guests"并仍然控制:

  1. 获奖者的数量
  2. 为每个访客在注册时提供即时反馈(获胜者/失败者)

Event.js

const eventSchema = new Schema({
  // 其他字段...
  guests: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Guest',
      default: null,
    },
    {
      giveaway_interest: {
        type: String,
      },
      redeemed: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
        updatedBy: String,
        comments: String,
      },
      notified: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
      },
      winner: {
        type: Boolean,
        default: 0,
      },
    },
  ],
  // 其他字段...
}, opts);

Guest.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const guestSchema = new Schema({
  // 其他字段...
  event: {
    type: Schema.Types.ObjectId,
    ref: 'Event',
    attended: String
  },
  // 其他字段...
});

这些更改应该允许您引用"guests"并仍然控制获奖者数量和为每个访客提供即时反馈。

英文:

I have an events model where guests can "signup" and join the event. Each event is a contest so it has a max amount of "guests" for each as certain slots are labeled as "winners". To ensure prizes aren't over allocated during the guest signups, I'd like to pre-built the embedded guests array as the event is created.

However, when doing so I receive cast error Cast to ObjectId failed for value "{}" (type Object) at path "guests" because I don't have objectIds for each guest yet...

This is by design as the placeholders are built with the "winner" or "loser" status so guests can immediately be notified as they sign up and are slotted into the array.

Is there a way to get my events model to reference guests and still control for:

  1. The number of winners
  2. Providing immediate feedback (winner/loser) to each guest as they sign up

Event.js

const eventSchema = new Schema({
  qr_name: {
    type: String,
    required: [true, 'Enter a name for your QR code'],
  },
  event_name: String,
  location_name: String,
  description: String,
  conversions: [ conversionsSchema ],
  image: [ImageSchema],
  address: String,
  geometry: {
    type: {
      type: String,
      enum: ['Point'],
    },
    coordinates: {
      type: [Number],
    }
  },
  user: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  qr: {
    type: Schema.Types.ObjectId,
    ref: 'Qr'
  },
  guests: [
    {
      type: Schema.Types.ObjectId,
      ref: 'Guest',
      default: null,
    },
    {
      giveaway_interest: {
        type: String,
      },
      redeemed: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
        updatedBy: String,
        comments: String,
      },
      notified: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
      },
      winner: {
        type: Boolean,
        default: 0,
      },
    },
  ],
  created: {
    type: Date,  // Captures both date and time
    default: Date.now
  },
  event_start: {
    type: Date,
    required: [true, 'Date & time of event start required']
  },
  event_end: {
    type: Date,
    required: [true, 'Date & time of event end required']
  },
}, opts);

Guest.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const guestSchema = new Schema({
    email: {
        type: String,
        default: null
    },
    firstName: {
        type: String,
        default: null
    },
    lastName: { 
        type: String,
        default: null
    },
    age: {
        type: Number,
        default: 0
    },
    gender: {
        type: String,
        enum: ['m', 'f'],
        default: null
    },
    phone: {
        type: Number,
        default: 0
    },
    zip: {
        type: Number,
        default: 0
    },
    dateAdded: {
        type: Date,
        default: Date.now
    },
    event: {
        type: Schema.Types.ObjectId,
        ref: 'Event',
        attended: String
    },
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    }
});

答案1

得分: 0

你的guests定义中有2个文档。根据你的描述,我认为你的意思是:

guests: [
    {
        guest: {
            type: Schema.Types.ObjectId,
            ref: 'Guest',
            default: null,
        },
        giveaway_interest: {
            type: String,
        },
        redeemed: {
            type: String,
            default: "No",
            date: {
                type: Date,
                default: Date.now,
            },
            updatedBy: String,
            comments: String,
        },
        notified: {
            type: String,
            default: "No",
            date: {
                type: Date,
                default: Date.now,
            },
        },
        winner: {
            type: Boolean,
            default: 0,
        },
    },
]

请参考:https://mongoosejs.com/docs/schematypes.html#arrays 和 https://masteringjs.io/tutorials/mongoose/array#document-arrays

我不认为在数组上“预先构建”是“确保奖品未分配过度”的理想解决方案,因为从一方面来看,数组项不太方便操作,而且拥有“空”子文档在没有应用程序逻辑的情况下不会解决任何问题。 除非你有保留模式的其他原因,我建议使用一个单独的查找集合。

英文:

You have 2 documents in the guests definition. Considering your description I believe you meant to have:

  guests: [
    {
      guest: {
        type: Schema.Types.ObjectId,
        ref: 'Guest',
        default: null,
      },
      giveaway_interest: {
        type: String,
      },
      redeemed: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
        updatedBy: String,
        comments: String,
      },
      notified: {
        type: String,
        default: "No",
        date: {
          type: Date,
          default: Date.now,
        },
      },
      winner: {
        type: Boolean,
        default: 0,
      },
    },
  ] 

See https://mongoosejs.com/docs/schematypes.html#arrays and https://masteringjs.io/tutorials/mongoose/array#document-arrays

I don't believe "prebuilding" of the array is an ideal solution "to ensure prizes aren't over allocated", as array items are not that convenient to manipulate from one hand, and having "empty" subdocuments doesn't solve anything without extensive logic on application side.
I'd go with a separate lookup collection, unless you have any other reasons to keep your schema.

huangapple
  • 本文由 发表于 2023年5月22日 22:57:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76307448.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定