mongoose populate not populating an array - node.js

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

Related

express.js mongoose populate 2 model

I'm want to join collection mongoDB but I've 2 model in project.
ADMINDETAIL and ADMINDETAIL get UID from member.model.js .
How I populate that.
queue.model.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var queueSchema = Schema(
{
QUEUE: String,
UID: String,
DATETIME: String,
ADMIN_ID: String,
USERDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
},
{
collection: "QUEUE"
}
);
var QUEUE = mongoose.model("QUEUE", queueSchema);
module.exports = QUEUE;
member.model.js
var mongoose = require("mongoose");
var memberSchema = mongoose.Schema(
{
UID: {type: String},
NAME: {type: String},
SURNAME: {type: String},
IDNUMBER: {type: String},
PHONE: {type: String},
ADDRESS: {type: String},
},
{
collection: "MEMBER"
}
);
var MEMBER = mongoose.model("MEMBER", memberSchema);
module.exports = MEMBER;
queue.router.js
// GET QUEUE BY USER
router.get("/byuid/:UID", (req, res) => {
var {UID} = req.params;
Queue.find({UID})
.populate({Path:"USERDETAIL",model:"MEMBER"})
.populate({Path:"ADMINDETAIL",model:"MEMBER"})
.exec((err, data) => {
if (err) return res.status(400).send(err);
return res.status(200).send(data);
});
});
Error I got.
TypeError: utils.populate: invalid path. Expected string. Got typeof `object`
change the type of filed from String to ObjectId like this:
USERDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
},
add your new data after that you can like this for population:
.populate("USERDETAIL ADMINDETAIL")
or
.populate([{
path: 'USERDETAIL ',
model: 'MEMBER'
}, {
path: 'ADMINDETAIL',
model: 'MEMBER'
}])
I think you are missing []

How to push data into array using mongoose, with schema having single only single object

I am learning Mongoose, and got struct on pushing data into array blogs.
my schema is
module.exports = function(mongoose) {
var UserSchema = new Schema({
count:String,
_id : {id:false},
blogs: [{ type: Schema.Types.ObjectId, ref: 'Blog' }]
},
{
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
});
var BlogSchema = new Schema({
blogs:[{
post : String,
title: String,
author : String,
userId: {
type: String,
default: function() {
return crypto.randomBytes(12).toString('hex');
}
},
_id: {type: String, required: true}
}],
});
var models = {
User : mongoose.model('User', UserSchema),
Blog : mongoose.model('Blog', BlogSchema)
};
return models;
}
Problem is here userSchema will always have/be a single object, whcih will keep track of count of total blogs.
I know it can be done using findOneAndUpdate but I don't have id/object created for UserSchema.
Any help is appreciated. Thanks

Mongoose, how do I join to collections using populate?

First Schema:
const ProviderSchema = new mongoose.Schema({
provName : { type: String, index: true }
});
module.exports = mongoose.model('provider', ProviderSchema);
Second Schema:
const WebProviderSchema = new mongoose.Schema({
userId : { type: Schema.Types.ObjectId, ref: 'users'},
providerId : { type: Schema.Types.ObjectId, ref: 'providers'}
});
module.exports = mongoose.model('webProvider', WebProviderSchema);
How do I join these two schemas?
So far if I do the following, I only get data from the second schema:
webProvider
.find({userId : '23423df234434bc956'})
.populate("providers")
.exec( function (error, listData) {
console.log(listData);
});
To populate you should use local field providerId. Should be .populate("providerId") instead of .populate("providers").
webProvider.find({userId : '23423df234434bc956'})
.populate("providerId")
.exec( function (error, listData) {
console.log(listData);
});
To populate multiple field can use like :
.populate("providerId userId")
or
.populate("providerId")
.populate("userId")

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

Error occured in nested sub-schema collections using mongoose

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.

Resources