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.
Related
I am writing a node express api with mongoose schema. I need to model a many-to-many relationship with additional attributes. My ER would be as following.
A normal many-to-many relationship would be like this:
var UserSchema = new Schema({
id: ObjectId,
username: { type: String, required: true },
...
courses: [ {type : mongoose.Schema.ObjectId, ref : 'Course'} ]
});
var CourseSchema = new Schema({
id: ObjectId,
name: { type: String, required: true },
...
students: [ {type : mongoose.Schema.ObjectId, ref : 'User'} ]
});
How can I model the additional attributes in the User-Course relationship?
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
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.
I have two Schemas Products and Users in different files. Products are belong to User and User have many Product
The Problem is, I have try to use Populate but somehow it return not what I expected.
here is my Schema for Product on models products.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var users = require('../models/users');
var Product = mongoose.Schema({
user_id : {type: String, required: true },
category_id : {type: String, default: null},
title : {type: String, required: true },
content : {type: String, default : "" },
pictureUrls : Array,
counter : {type : Number, default : 0},,
lowercaseTitle : {type: String, default : null },
_user : { type: Schema.Types.ObjectId, ref: users.User }
});
Product.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('Product', Product)
and this is my Schema for User on models users.js
var mongoose = require('mongoose');
var User = mongoose.Schema({
firstName : {type: String, default: "" },
lastName : {type: String, default: "" },
username : {type: String, required: true },
email : {type: String, required: true },
password : {type: String, default: "" },
bio : {type: String, default: "" },
website : {type: String, default: "" },
phone : {type: String, default: "" },
gender : {type: String, default: "" },
birthDate : {type: Date, default: null },
avatarUrl : {type: String, default: "" },
verified : {type : Boolean, default : false}
});
User.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('User', User);
currently I am using method find by calling each Models
User.findOne({"sessionToken" : bearerHeader}, function (err, user){
Product.find({"user_id" : user._id}, function (err, products){
console.log(products);
});
});
but it takes time and became problem if there related to another models.
I'm calling populte with this
Product.findOne({}).populate('_user').exec(function(err, p){
console.log(p);
});
but attribute _user was not set and undefined
any help?
Thanks
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