Error occured in nested sub-schema collections using mongoose - node.js

I need a nested subschema having ids so i tried the below code but data cant inserted
code
My model..
var connection= handler.getConnection();
console.log(connection);
autoIncrement.initialize(connection);
var subSchema = mongoose.Schema({
course_Submodule: [{
type: String,
required: true,
}]
},{ _id : false });
subSchema.plugin(autoIncrement.plugin, {
model: 'Submodule',
field: 'Id_submodule',
startAt: 1,
incrementBy: 1
});
var courseSchema = new Schema({
course_Name: String,
course_Code: String,
course_Submodule: [subSchema],
course_Author: String,
id_subject: String,
id_user: String,
});
courseSchema.plugin(autoIncrement.plugin, {
model: 'Course',
field: 'Id_course',
startAt: 1,
incrementBy: 1
});
var Course = connection.model('Course', courseSchema);
var Submodule = connection.model('Submodule', subSchema);
module.exports = Course;
bt in db data is inserted like this
"_id" : ObjectId("578efe6da667fff80d09d5ed"),
"Id_course" : 214,
"course_Name" : "chemistry1",
"course_Code" : "ch1",
"course_Author" : "David",
"id_subject" : "3",
"course_Submodule" : [
{
"Id_submodule" : 14,
"course_Submodule" : [ ]
},
{
"Id_submodule" : 15,
"course_Submodule" : [ ]
}
],
"__v" : 0
trying these code i cant insert the value of course_Submodule.Is ther any anotherway for this .help me please

Instead of duplicating the data, you can simply store the object id of the other object into your schema.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Schema for doctors
var StudentSchema = new Schema({
name:{
type: String,
required: true
},
email: {
type: String,
unique: true
},
user : {
type : Schema.ObjectId,
ref: 'User', //i have a different model User
required : true
}
});
module.exports = mongoose.model('Student', StudentSchema);
Your query over student schema can look like this
db.collection.find(//condition, function(err, data){
//your functionality
})
.populate('User', 'dob')
.exec();
My user schema has a field dob.
This is a small and tidy example to avoid duplicacy of data.
Hope it will help.

Related

Mongoose populate returning data without population

I know that this question was asked many many times but i still can't find a solution
So this is my db
Product :
Ingredient :
Schemas :
ingredient.js
const mongoose = require("mongoose");
var IngredientSchema = new mongoose.Schema({
quantity: {
value: Number,
unit: String
},
comment: String,
product: { type: mongoose.Schema.Types.ObjectId, ref: "Product" }
});
module.exports = mongoose.model("IngredientSchema", IngredientSchema);
product.js
const mongoose = require("mongoose");
var ProductSchema = new mongoose.Schema({
name: {
type: String,
default: "",
trim: true,
required: "Name cannot be blank"
},
category: {
type: String,
default: "",
trim: true
},
convertion: [
{
unit_from: String,
unit_to: String,
value_from: Number,
value_to: Number
}
],
default_unit: String
});
const Product = (module.exports = mongoose.model(
"ProductSchema",
ProductSchema
));
this is the populate function :
ingredientRoutes.route("/:id").get(function(req, res) {
let id = req.params.id;
Ingredient.findById(id)
.populate("produit")
.exec()
.then(function(data) {
console.log(data.product, "***");
})
.catch(function(err) {
console.log(err);
});
});
this is the result that i'm getting :
just the id of the product without making the population
Any idea ?

Populate Schema on Mongoose

I have two collections one is users and another is cats. I want cats data under my users collection. But I am not getting.
User.js
var Schema = mongoose.Schema;
var userSchema = Schema({
_id: Schema.Types.ObjectId,
username: String,
email: { type: String, unique: true, lowercase: true, trim: true },
password: String,
role: String,
cats: [{ type: Schema.ObjectId, ref: 'Cat' }]
});
var User = mongoose.model('User', userSchema);
exports.default = User;
Cat.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var catSchema = Schema({
fname: String,
mname: String,
lname: String,
});
var Cat = mongoose.model('Cat', catSchema);
exports.default = Cat;
O/p
"_id" : ObjectId("5a446ab43533970b8489e1ac"),
"username" : "xyz",
"email" : "xyz#gmail.com",
"password""$2a$10$ogerY6OiCRKy9TjPYERaOugUJeqelBl.yToJ4ZBX3ac2MVZQpsKOu",
"role" : "user",
"cats" : [ ],
"__v" : 0
Expected Output
"_id" : ObjectId("5a446ab43533970b8489e1ac"),
"username" : "xyz",
"email" : "xyz#gmail.com",
"password""$2a$10$ogerY6OiCRKy9TjPYERaOugUJeqelBl.yToJ4ZBX3ac2MVZQpsKOu",
"role" : "user",
"cats" : [{
"_id" : ObjectId("5a44707effc66a234447c36b"),
"fname" : "felix",
"mname" : "",
"lname" : "",
} ],
"__v" : 0
You might combine them into just one schema like below.
No any reason to create schemas separately unless the array count increases a couple of hundreds continuously..
var Schema = mongoose.Schema;
var userSchema = Schema({
_id: Schema.Types.ObjectId,
username: String,
email: { type: String, unique: true, lowercase: true, trim: true },
password: String,
role: String,
cats: [
{
_id: Schema.Types.ObjectId,
fname: String,
mname: String,
lname: String,
}
]
});
var User = mongoose.model('User', userSchema);
exports.default = User;
Fix your schema (should be cats: [{ type: Schema.Types.ObjectId, ref: 'Cat' }] and refer to http://mongoosejs.com/docs/populate.html.
You can get data like this, using model.find().populate('ref')
const story = await User.find().populate('Cat');
It will return all the users and against each user, an array of respective Cat. You already mentioned the ref of the Cat in the User model, so you don't need to do anything extra.

mongoose aggregate returning empty array

I have two model and I want to find the last status of each id in customer model from the status model, I'm using aggregate here, but when I console log things it shows, empty, can anyone help please .............................................
/// customer model
///table name is crmcustomers in database
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schemaOptions = {
timestamps: true,
toJSON: {
virtuals: true
}
};
var CrmCustomerSchema = new Schema({
name: String,
shop_name: String,
address: String,
phone: { type: String, unique: true},
comment: String,
email: String,
website : String,
interest: String,
reference : String,
}, schemaOptions);
var CrmCustomer = mongoose.model('CrmCustomer', CrmCustomerSchema);
module.exports = CrmCustomer;
/// status model
///table name is crmcustomerstatuses in database
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schemaOptions = {
timestamps: true,
toJSON: {
virtuals: true
}
};
var CrmCustomerStatusSchema = new Schema({
crm_id : String,
name: String,
shop_name : String,
status : String
}, schemaOptions);
var CrmCustomerStatus = mongoose.model('CrmCustomerStatus', CrmCustomerStatusSchema);
module.exports = CrmCustomerStatus;
////query
CrmCustomer.aggregate([
{
"$lookup": {
"from": "crmcustomerstatus",
"localField": "_id",
"foreignField": "crm_id",
"as": "result"
}
},
]).exec(function(err, results){
console.log(results);
})
///result
[ { _id: 5a1cf755b5268904a476c7d2,
updatedAt: 2017-11-28T05:42:45.239Z,
createdAt: 2017-11-28T05:42:45.239Z,
name: 'istiaque ahmad',
shop_name: 'les mecaron',
address: 'mirpur',
phone: '01764199657',
email: 'nahid#bond.com',
website: 'xccxxxxx',
comment: 'dsfsdf',
interest: 'dsfsdf',
reference: 'dsfsdfsdf',
__v: 0,
result: [] } ]
Reason for getting empty result is _id in CrmCustomer schema is of type of ObjectId, whereas crm_id in CrmCustomerStatus schema is of type String
Modified CrmCustomerStatus Schema
var CrmCustomerStatusSchema = new Schema({
crm_id : ObjectId,
name: String,
shop_name : String,
status : String

Mongoose Refs to children

I am struggling to find examples or documentation on mongoose children population.
http://mongoosejs.com/docs/populate.html
On the documentation they have:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: 'Person' },
title : String,
fans : [{ type: Number, ref: 'Person' }]
});
var Story = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);
It makes sense, a Person can have many stories thus the 'parent' field 'stories' which has a list of all the stories in.
What I am struggling to understand is how do you push the the story into the person schema.
For example, i have an assignment schema:
var mongoose = require ( 'mongoose' ),
Schema = mongoose.Schema;
var assignmentSchema = new Schema (
{
_id: String,
assignName: String,
modInsID: [{ type: Schema.Types.Number, ref: 'ModuleInst' }],
studentAssigns: [{type: Schema.Types.ObjectId, ref: 'StudentAssign' }]
}
);
module.exports = mongoose.model ( 'Assignment', assignmentSchema );
The studentAssigns stores all the id's of the studentAssigns which then can be used with the .pre middleware for cascade deleting.
So now my StudentAssign schema:
var mongoose = require ( 'mongoose' ),
autoIncrement = require ( 'mongoose-auto-increment' ),
Schema = mongoose.Schema;
var connection = mongoose.createConnection("************");
autoIncrement.initialize(connection);
var studentAssignSchema = new Schema (
{
assID: [{ type: Schema.Types.String, ref: 'Assignment' }],
studentID: [{ type: Schema.Types.Number, ref: 'Student' }]
}
);
var StudentAssign = connection.model('StudentAssign', studentAssignSchema);
module.exports = mongoose.model ('StudentAssign', studentAssignSchema );
As you can see it already is referencing 'Assignment'
Here is my api code:
studentAssign POST:
router.route('/student-assignment').post( function(req, res) {
var studentAssign = new StudentAssign();
studentAssign.assID = req.body.assID;
studentAssign.studentID = req.body.studentID;
studentAssign.save(function(err, studentAssign) {
if(err) console.log(err);
res.status(200).json(studentAssign);
});
})
So that's the part I am confused at where would I push the 'studentAssign' into 'Assignment' schema's 'studentAssigns array ??
here is my current api json callback:
[
{
"_id": "As 1",
"assignName": "Software Implementation",
"__v": 0,
"studentAssigns": [],
"modInsID": [
{
"_id": 22,
"semester": "TRI 3",
"year": 2016,
"__v": 0,
"modID": [
111
]
}
]
}
]
The documentation just does not make it clear as they just show:
aaron.stories.push(story1);
aaron.save(callback);
With no explanation?
I have attempted:
var assignment = new Assignment();
assignment.studentAssigns.push(studentAssign); and nothing gets stored ??
Here is a working example based on the documentation docs
const mongoose = require('mongoose');
const { Schema } = mongoose;
const personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
const storySchema = Schema({
author: { type: Schema.Types.ObjectId, ref: 'Person' },
title: String,
fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);
Person model has its stories field set to an array of ObjectId's
For saving Refs to children you may have first to save stories before pushing them to Person's stories field
const story1 = new Story({
title: 'Casino Royale',
author: author._id // assign the _id from the person
});
story1.save();
And before pushing story1 find the author id you want to push to
const author = await Person.findOne({_id: "624313f302e268b597b8df1f"})
if(Array.isArray(author.stories)) author.stories.push(story1);
author.save()
You model states :
assID: [{ type: Schema.Types.String, ref: 'Assignment' }],
studentID: [{ type: Schema.Types.Number, ref: 'Student' }]
I think from your code you don't want to store multiple assignments in assID and multiple Students in studentID. Modify your model to
assID: { type: Schema.Types.String, ref: 'Assignment' },
studentID: { type: Schema.Types.Number, ref: 'Student' }
Your save code can stay the same.
If you do want to store for example multiple assignments, you need to push them into the assID array ;-)
router.get('/author', (req, res, next) => {
Person.
find().
exec( (err, person) => {
if (err) return handleError(err)
Story.find({author: person[0]._id}).
exec( (err, story) => {
if (err) return handleError(err)
person[0].stories.push(story[0])
res.json( { person: person })
})
})
})

mongoose populate not populating an array

I am facing an issue where mongoose query is not populating an array type.
Here is institute schema
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var InstituteSchema = new Schema({
name: String,
address: String,
city: String,
country: String,
zip: String,
owner: { type: mongoose.Schema.ObjectId, ref: 'User' },
teachers: [{type: mongoose.Schema.ObjectId, ref: 'Teacher'}],
categories: [String],
created : { type : Date, default : Date.now }
});
module.exports = mongoose.model('Institute', InstituteSchema);
And here is teacher Schema
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TeacherSchema = new Schema({
education: [{degree: String, instituteName: String}],
dob: Date,
photoUrl: String,
phoneNumber: String,
owner: {type: mongoose.Schema.ObjectId, ref: 'User'},
institutes: [{type: mongoose.Schema.ObjectId, ref: 'Institute'}],
subjects: [{type: mongoose.Schema.ObjectId, ref: 'Subject'}],
created : { type : Date, default : Date.now }
})
module.exports = mongoose.model('Teacher', TeacherSchema);
Here is a method which queries the institute by owner id
exports.mine = function (req, res, next) {
var ObjectId = mongoose.Types.ObjectId;
var userId = new ObjectId(req.user._id);
Institute.find({
owner: userId
}).populate('teachers').exec(function (err, institute) {
if (err) return next(err);
if (!institute) return res.json(401);
res.json(institute);
});
};
I can see from the db that institute has teacher added
db.institutes.find();
{
"_id" : ObjectId("554719a9f5be11c6d4369264"),
"owner" : ObjectId("5547199bf5be11c6d4369263"),
"country" : "USA",
"name" : "Raghvendra Singh",
"address" : "38589 Royal Ann Cmn",
"city" : "Fremont",
"zip" : "94536",
"created" : ISODate("2015-05-04T07:03:05.569Z"),
"categories" : [ "IIT", "Medical" ],
"teachers" : [ ObjectId("55471965f5be11c6d436925f") ],
"__v" : 3
}
But somehow the query method doesn't populate the teachers collection. The weird thing is that i don't even get the collection with object ids and it returns and institute with empty teacher array.
And when i remove the .populate('teachers') from the method call it indeed returns the teacher array with object ids.
I looked at the documentation and i can't see what am i doing wrong.
First you need to change your Model slightly as mention for teachers feild.
teachers: [ { teacher: { type: Schema.ObjectId, ref: "Teacher" } } ]
exports.mine = function (req, res, next) {
var ObjectId = mongoose.Types.ObjectId;
var userId = new ObjectId(req.user._id);
Institute.find({
owner: userId
}).populate('**teachers.teacher**').exec(function (err, institute) {
if (err) return next(err);
if (!institute) return res.json(401);
res.json(institute);
});
};
Then, change your populate parameter to teachers.teacher . It will work

Resources