46

I'm building a Mongoose schema for a dating app.

I want each person document to contain a reference to all the events they've been to, where events is another schema with its own models in the system. How can I describe this in the schema?

var personSchema = mongoose.Schema({
    firstname: String,
    lastname: String,
    email: String,
    gender: {type: String, enum: ["Male", "Female"]}
    dob: Date,
    city: String,
    interests: [interestsSchema],
    eventsAttended: ???
});
CodyBugstein
  • 21,984
  • 61
  • 207
  • 363

3 Answers3

92

You can do so by using Population

Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s). We may populate a single document, multiple documents, plain object, multiple plain objects, or all objects returned from a query.

Suppose your Event Schema is defined as follows:

var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var eventSchema = Schema({
    title     : String,
    location  : String,
    startDate : Date,
    endDate   : Date
});

var personSchema = Schema({
    firstname: String,
    lastname: String,
    email: String,
    gender: {type: String, enum: ["Male", "Female"]}
    dob: Date,
    city: String,
    interests: [interestsSchema],
    eventsAttended: [{ type: Schema.Types.ObjectId, ref: 'Event' }]
});

var Event  = mongoose.model('Event', eventSchema);
var Person = mongoose.model('Person', personSchema);

To show how populate is used, first create a person object,

aaron = new Person({firstname: 'Aaron'}) and an event object,

event1 = new Event({title: 'Hackathon', location: 'foo'}):

aaron.eventsAttended.push(event1);
aaron.save(callback); 

Then, when you make your query, you can populate references like this:

Person
.findOne({ firstname: 'Aaron' })
.populate('eventsAttended') // only works if we pushed refs to person.eventsAttended
.exec(function(err, person) {
    if (err) return handleError(err);
    console.log(person);
});
chridam
  • 100,957
  • 23
  • 236
  • 235
  • 2
    can I ask you a question? What if I wanted to also have a list of `attendees` in the `event` schema? Would that cause a circular loop problem? – CodyBugstein Mar 16 '15 at 20:01
  • 4
    You can create simultaneous references in two directions without any possible circular dependencies. The example of the [**Story and Person schemas**](http://mongoosejs.com/docs/populate.html) in the Mongoose docs explains this well. – chridam Mar 16 '15 at 20:10
  • 3
    What will be TypeScript of eventsAttended? – Ali Sajid Mar 06 '19 at 04:55
  • @AliSajid did you find out? – winklerrr May 06 '22 at 07:18
0

To reference the ObjectId of one table in another table refer below code

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

const otpSchema = new mongoose.Schema({
    otpNumber:{
        type: String,
        required: true,
        minlength: 6,
        maxlength: 6
    },
    user:{
        type: Schema.Types.ObjectId,
        ref: 'User'
    }
});

const Otp = mongoose.model('Otp',otpSchema);

// Joi Schema For Otp
function validateOtp(otp) {
    const schema = Joi.object({
        otpNumber: Joi.string().max(6).required(),
        userId: Joi.objectId(),   // to validate objectId we used 'joi-objectid' npm package
        motive: Joi.string().required(),
        isUsed: Joi.boolean().required(),
        expiresAt: Joi.Date().required()
    });
    // async validate function for otp
    return schema.validateAsync(otp);
}

exports.Otp = Otp;
exports.validateOtp = validateOtp;
-1

List item

var personSchema = mongoose.Schema({
    firstname: String,
    lastname: String,
    email: String,
    gender: {
        type: String,
        enum: ["Male", "Female"]
    }
    dob: Date,
    city: String,
    interests: [interestsSchema],
    eventsAttended[{
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: "Place"
    }], 
**//ref:"Places"...you have put the other model name**
 *OR*
    eventsAttended[{
        type: mongoose.Types.ObjectId,
        required: true,
        ref: "Place"
    }],
});
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 15 '22 at 00:21