如何在我的Mongoose模式中引用另一个模式?

46

我正在为交友应用程序构建Mongoose模式。

我希望每个person文档都包含对其参加的所有活动的引用,其中events是系统中具有自己模型的另一个模式。我该如何在模式中描述这一点?

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

7
我理解你希望翻译的内容是这样的:eventsAttended: [{ type: app.mongoose.Schema.ObjectId, ref: 'Event'}],其中包括一个类型为app.mongoose.Schema.ObjectIdeventsAttended属性和引用了'Event'的对象。 - Sergio Tulentsev
3个回答

94
你可以使用Population来实现。Population是自动将文档中指定路径替换为另一个集合中的文档的过程。我们可以填充单个文档、多个文档、纯对象、多个纯对象或查询返回的所有对象。假设你的事件模式定义如下:
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);
为了展示populate的使用方法,首先创建一个人对象, aaron = new Person({firstname: 'Aaron'}) 和一个事件对象, event1 = new Event({title: 'Hackathon', location: 'foo'}):
aaron.eventsAttended.push(event1);
aaron.save(callback); 

然后,当您进行查询时,可以像这样填充引用:

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);
});

2
我能问你一个问题吗?如果我想在“事件(event)”架构中也有一个“参与者(attendees)”列表,那会引起循环往复的问题吗? - CodyBugstein
4
在不可能出现循环依赖的情况下,您可以创建两个方向上的同时引用。 Mongoose文档中Story and Person schemas的例子很好地解释了这一点。 - chridam
3
eventsAttended 的 TypeScript 类型会是什么? - Ali Sajid
@AliSajid 你找到了吗? - winklerrr

0

要在一张表中引用另一张表的ObjectId,请参考以下代码

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

列表项

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"
    }],
});

目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接