我是mongodb的新手,我正在玩一个自我项目,用户可以订阅预定义的3-4个不同的课程。每门课程每天一小时,学生可以订阅15天、30天或更长时间。
App将存储学生的信息,他们订阅了多少天和多少天的课程。
这是我的猫鼬模式。
var mongoose = require('mongoose');
var schemaOptions = {
timestamps: true,
toJSON: {
virtuals: true
}
};
var courseSchema = new mongoose.Schema({
name: String
});
var studentSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true},
phone: String,
gender: String,
age: String,
city: String,
street: String,
picture: String,
course: [courseSchema],
subscriptionDays: Number,
daysPresent: [Date]
}, schemaOptions);
module.exports = mongoose.model('Student', studentSchema);在这里,course是3-4门课程中的任何一门,一个学生可以同时订阅一个或多个课程.subscriptionDays是他们订阅的天数,daysPresent是他们参加这个课程的天数。
我不确定这是否是我的项目的正确模式,到目前为止我已经能够做到这一点。
与模式的混淆如下:
courseSchema,
var courseSchema =新mongoose.Schema({ name: String,subsriptionDays: Number,daysPresent: Date });但是,在这样做之后,我仍然困惑于对数据进行更改,比如每次学生参加课程时都必须将Date插入到文档中。
Date。我能从蒙古专家那里得到一些指导和建议吗?提亚
发布于 2017-06-17 07:45:01
我认为你对扩展设计的第二个想法基本上是正确的。我只想对此进行扩展,包括对“课程”本身的“引用”,而不仅仅是嵌入在模式中的信息。
在您的用例问题中,最好用一个工作示例来解决它们:
const async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = Schema.Types.ObjectId;
mongoose.set('debug',true);
mongoose.connect('mongodb://localhost/school');
// Course model
const courseSchema = new Schema({
name: String,
info: String
});
const Course = mongoose.model('Course', courseSchema);
// Student Model
const studentCourseSchema = new Schema({
_id: { type: ObjectId, ref: 'Course' },
name: String,
subscriptionDays: Number,
daysPresent: [Date]
});
const studentSchema = new Schema({
name: String,
email: String,
courses: [studentCourseSchema]
});
studentSchema.index({ "email": 1 },{ "unique": true, "background": false });
const Student = mongoose.model('Student', studentSchema);
function logOutput(content) {
console.log( JSON.stringify( content, undefined, 2 ) )
}
async.series(
[
// Clear collections
(callback) =>
async.each(mongoose.models,
(model,callback) => model.remove({},callback),callback),
// Set up data
(callback) =>
async.parallel(
[
(callback) => Course.insertMany(
[
{ "name": "Course 1", "info": "blah blah blah" },
{ "name": "Course 2", "info": "fubble rumble" }
],
callback),
(callback) => Student.insertMany(
[
{ "name": "Bill", "email": "bill@example.com" },
{ "name": "Ted", "email": "ted@example.com" }
],
callback)
],
callback
),
// Give bill both courses
(callback) => {
async.waterfall(
[
(callback) => Course.find().lean().exec(callback),
(courses,callback) => {
courses = courses.map(
course => Object.assign(course,{ subscriptionDays: 5 }));
let ids = courses.map( c => c._id );
Student.findOneAndUpdate(
{ "email": "bill@example.com", "courses._id": { "$nin": ids } },
{ "$push": {
"courses": {
"$each": courses
}
}},
{ "new": true },
(err, student) => {
logOutput(student);
callback(err);
}
)
}
],
callback
)
},
// Attend one of bill's courses
(callback) => Student.findOneAndUpdate(
{ "email": "bill@example.com", "courses.name": 'Course 2' },
{ "$push": { "courses.$.daysPresent": new Date() } },
{ "new": true },
(err, student) => {
logOutput(student);
callback(err);
}
),
// Get Students .populate()
(callback) => Student.find().populate('courses._id')
.exec((err,students) => {
logOutput(students);
callback(err);
}
)
],
(err) => {
if (err) throw err;
mongoose.disconnect();
}
)因此,这将为您提供一个示例,说明您询问的操作实际上是如何工作的。
$push功能。为了确保您没有添加已经存在的课程,如果"query“表达式已经存在于”课程“数组中,则实际上会排除所选内容。在这个示例中,传递了一个"list“,因此我们使用$nin,但是对于单个项,您只需使用$ne:
{“电子邮件”:"bill@example.com","courses._id":{ "$nin":ids } },{ "$push":{“课程”:{ "$each":课程} },$push运算符,以便可以附加到"daysPresent"数组,还可以使用位置$运算符来指向与匹配条件相对应的正确的数组索引位置:
{“电子邮件”:"bill@example.com","courses.name":'Course 2‘},{ "$push":{ "courses.$.daysPresent":new Date() },另外,还有一些操作显示了在自己的集合中保留一个"Courses"列表与您可能不希望嵌入到每个学生身上的其他信息之间的关系。
示例中的最后一个操作实际上执行一个.populate(),从其他集合中实际提取此信息以供显示。
整个示例都使用mongoose.set('debug',true);进行了调试,这样您就可以看到对MongoDB的实际调用对每个操作都做了什么。
还可以了解这里使用的.findOneAndUpdate()方法,以及来自核心MongoDB文档的各种“更新操作员”。
样本输出
Mongoose: courses.remove({}, {})
Mongoose: students.remove({}, {})
Mongoose: students.ensureIndex({ email: 1 }, { unique: true, background: false })
(node:10544) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
Mongoose: courses.insertMany([ { __v: 0, name: 'Course 1', info: 'blah blah blah', _id: 5944d5bc32c6ae2930174289 }, { __v: 0, name: 'Course 2', info: 'fubble rumble', _id: 5944d5bc32c6ae293017428a } ], null)
Mongoose: students.insertMany([ { __v: 0, name: 'Bill', email: 'bill@example.com', _id: 5944d5bc32c6ae293017428b, courses: [] }, { __v: 0, name: 'Ted', email: 'ted@example.com', _id: 5944d5bc32c6ae293017428c, courses: [] } ], null)
Mongoose: courses.find({}, { fields: {} })
Mongoose: students.findAndModify({ 'courses._id': { '$nin': [ ObjectId("5944d5bc32c6ae2930174289"), ObjectId("5944d5bc32c6ae293017428a") ] }, email: 'bill@example.com' }, [], { '$push': { courses: { '$each': [ { daysPresent: [], _id: ObjectId("5944d5bc32c6ae2930174289"), name: 'Course 1', subscriptionDays: 5 }, { daysPresent: [], _id: ObjectId("5944d5bc32c6ae293017428a"), name: 'Course 2', subscriptionDays: 5 } ] } } }, { new: true, upsert: false, remove: false, fields: {} })
{
"_id": "5944d5bc32c6ae293017428b",
"__v": 0,
"name": "Bill",
"email": "bill@example.com",
"courses": [
{
"subscriptionDays": 5,
"name": "Course 1",
"_id": "5944d5bc32c6ae2930174289",
"daysPresent": []
},
{
"subscriptionDays": 5,
"name": "Course 2",
"_id": "5944d5bc32c6ae293017428a",
"daysPresent": []
}
]
}
Mongoose: students.findAndModify({ 'courses.name': 'Course 2', email: 'bill@example.com' }, [], { '$push': { 'courses.$.daysPresent': new Date("Sat, 17 Jun 2017 07:09:48 GMT") } }, { new: true, upsert: false, remove: false, fields: {} })
{
"_id": "5944d5bc32c6ae293017428b",
"__v": 0,
"name": "Bill",
"email": "bill@example.com",
"courses": [
{
"subscriptionDays": 5,
"name": "Course 1",
"_id": "5944d5bc32c6ae2930174289",
"daysPresent": []
},
{
"subscriptionDays": 5,
"name": "Course 2",
"_id": "5944d5bc32c6ae293017428a",
"daysPresent": [
"2017-06-17T07:09:48.662Z"
]
}
]
}
Mongoose: students.find({}, { fields: {} })
Mongoose: courses.find({ _id: { '$in': [ ObjectId("5944d5bc32c6ae2930174289"), ObjectId("5944d5bc32c6ae293017428a") ] } }, { fields: {} })
[
{
"_id": "5944d5bc32c6ae293017428b",
"__v": 0,
"name": "Bill",
"email": "bill@example.com",
"courses": [
{
"subscriptionDays": 5,
"name": "Course 1",
"_id": {
"_id": "5944d5bc32c6ae2930174289",
"__v": 0,
"name": "Course 1",
"info": "blah blah blah"
},
"daysPresent": []
},
{
"subscriptionDays": 5,
"name": "Course 2",
"_id": {
"_id": "5944d5bc32c6ae293017428a",
"__v": 0,
"name": "Course 2",
"info": "fubble rumble"
},
"daysPresent": [
"2017-06-17T07:09:48.662Z"
]
}
]
},
{
"_id": "5944d5bc32c6ae293017428c",
"__v": 0,
"name": "Ted",
"email": "ted@example.com",
"courses": []
}
]发布于 2017-06-17 04:29:34
架构,您可以定义如下:
var mongoose = require('mongoose');
var courseSchema = new mongoose.Schema({
name: String
});
var studentSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true},
phone: String,
gender: String,
age: String,
city: String,
street: String,
picture: String,
courses: [{
course:{type:mongoose.Schema.Types.ObjectId,ref:'courseSchema'},
isAttending:{type:Boolean ,default:false}
}],
subscriptionDays: Number,
daysPresent: [Date]
}, schemaOptions);
module.exports = mongoose.model('Student', studentSchema);isAttending将解决您的问题,如果学生订阅3门课程,并去特定的一门课程,那么isAttending将是正确的,否则错误。
谢谢
https://stackoverflow.com/questions/44600205
复制相似问题