I am working with mongo DB and mongoose and I'm getting the following error when running the code below.
"MissingSchemaError: Schema hasn't been registered for model "Project".\nUse mongoose.model(name, schema)"
import {...}
const { school } = request.params;
const document = await Document.find({
}).populate('project').lean();
if (document.project.school != school)
throw HTTP.forbidden('ERROR.DOCUMENT_DOES_NOT_BELONG_TO_YOUR_SCHOOL');
My schemas look as follows
const Document = new Schema({
name: { type: String },
type: { type: String },
project: {
type: Schema.Types.ObjectId,
ref: 'Project'
}
}, {
timestamps: true
});
const Project = new Schema({
name: { type: String },
school: {
type: Schema.Types.ObjectId,
ref: 'School'
}
}, {
timestamps: true
});
const School = new Schema({
name: { type: String },
curriculum: [{
type: Schema.Types.ObjectId,
ref: 'Curriculum'
}],
}, {
timestamps: true
});
Does anyone know what I need to do to overcome this everything has been initialised by the time this section of code is getting called?
Assuming you have created model for each schema, try writing your refs using lowercase:
const Document = new Schema({
name: { type: String },
type: { type: String },
project: {
type: Schema.Types.ObjectId,
ref: 'project'
}
}, {
timestamps: true
});
const Project = new Schema({
name: { type: String },
school: {
type: Schema.Types.ObjectId,
ref: 'school'
}
}, {
timestamps: true
});
const School = new Schema({
name: { type: String },
curriculum: [{
type: Schema.Types.ObjectId,
ref: 'curriculum'
}],
}, {
timestamps: true
});
Related
I'm trying to fetch data from below mongoose schema, But I'm not sure how to fetch the role field, which is a type of RoleObject.
import * as mongoose from 'mongoose';
const Schema = mongoose.Schema;
const RoleObject = {
current_role: {
type: Schema.Types.ObjectId,
ref: 'Role',
autopopulate: true
},
new_role: {
type: Schema.Types.ObjectId,
ref: 'Role',
autopopulate: true
}
}
const UserRequestSchema = new mongoose.Schema({
group: {
type: Schema.Types.ObjectId,
ref: 'Group',
autopopulate: true,
required: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
autopopulate: true,
required: true
},
role: {
type: RoleObject
},
status: {
type: String,
required: true,
enum: ['pending', 'approved', 'denied']
},
type: {
type: String,
required: true,
enum: ['group-join', 'role-change']
},
active: {
type: Boolean,
required: true
}
});
UserRequestSchema.index( { group: 1, user: 1 }, { unique: true } );
export { UserRequestSchema };
Here I want populate the role field from the UserRequestSchema, which is given as RoleObject.
Is it possible through populate the field using find method or do I need to use aggregation ?
Try this
UserRequest.find({active:true}).populate({
path: 'role.current_role role.new_role',
model: 'Role',
select: 'name'
}).exec((error, result) => {
if (error) {
console.log(error, " ERROR")
}
console.log(result, "Result")
});
If you face any issue. Please let me know
i want to check if current user is following other use lets say check if user A is following user B.
User Model:-
const UserSchema = new Schema({
email: {
required: true,
type: String,
unique: true,
lowercase: true,
validate: (value) => {
if (!validator.isEmail(value)) {
throw new Error('Invalid email address.');
}
}
},
fullName: {
required: true,
type: String,
},
username: {
required: true,
type: String,
unique: true,
lowercase: true,
minlength: 3,
},
password: {
type: String,
minlength: 8,
},
avatar: String,
bio: {
type: String,
default: null,
maxlength:300,
},
location: {
type: String,
default: 'Bangalore'
},
website: {
type: String,
default: null,
},
joindate: {
type: Date,
default: new Date()
},
isVerified:{
type:Boolean,
default:false,
}
})
const UserModel = mongoose.model('User', UserSchema);
module.exports = UserModel;
Followings Model:-
const FollowingsSchema = new Schema({
user: {
ref: 'User',
unique:true,
type: Schema.Types.ObjectId,
},
followings: [{
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}]
})
const Followings = mongoose.model('Followings', FollowingsSchema);
module.exports = Followings;
Followers Model:-
const FollowersSchema = new Schema({
user: {
ref: 'User',
unique:true,
type: Schema.Types.ObjectId,
},
followers: [{
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}]
})
const Followers = mongoose.model('Followers', FollowersSchema);
module.exports = Followers;
currently i was able to achieve this by iterating through each follower and check if user exist in that user followers list.
i want to achieve this with mongodb aggregation ,im new to mongob
I have 2 collection: Category and book
Book:
const mongoose = require('mongoose');
// eslint-disable-next-line camelcase
const mongoose_delete = require('mongoose-delete');
const { Schema } = mongoose;
const SchemaTypes = mongoose.Schema.Types;
const Book = new Schema({
name: { type: String },
price: { type: Number },
images: { type: Array },
country: { type: String },
author: { type: String },
publicationDate: { type: String },
description: { type: String },
category: { type: SchemaTypes.ObjectId, ref: 'Category' },
date: { type: Date, default: Date.now },
}, {
timestamps: true,
});
Book.plugin(mongoose_delete);
Book.plugin(mongoose_delete, { overrideMethods: 'all', deletedAt: true });
module.exports = mongoose.model('Book', Book);
Category:
const mongoose = require('mongoose');
// eslint-disable-next-line camelcase
const mongoose_delete = require('mongoose-delete');
const SchemaTypes = mongoose.Schema.Types;
const { Schema } = mongoose;
const Category = new Schema({
name: { type: String, required: true },
image: { type: String },
products: [{ type: SchemaTypes.ObjectId, ref: 'Book' }],
date: { type: Date, default: Date.now },
}, {
timestamps: true,
});
Category.plugin(mongoose_delete);
Category.plugin(mongoose_delete, { overrideMethods: 'all', deletedAt: true });
module.exports = mongoose.model('Category', Category);
and I select all the books received on the list:
{
_id: new ObjectId("623668ac5b1d392b37690cbc"),
name: 'The Godfather',
price: 110000,
country: 'U.S',
publicationDate: '1969',
category: new ObjectId("6238fdf64f60303756b60b20"),
author: 'Mario Puzo',
... : ...
}
And I want to display the category name on the product list, how do I do it?
**like: {{book.category.name}}
{{book.category.image}}
?**
Since you are using Mongoose, you can use populate() method. You can do it like this:
const books = await Books.find().populate('category')
try $lookup (aggregation)
Book.aggregate([{
$lookup: {
from: "Category",
localField: "category",
foreignField: "_id",
as: "category"
}
}]).exec(function(err, students) {
});
I have user model
const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const userSchema = mongoose.Schema({
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isEmailVerified: { type: Boolean },
registrationStep: { type: Number, enum: [0,1,2,3]},
regDate: { type: Date },
companyName: { type: String },
oib: { type: String },
telephone: { type: String },
address: { type: String },
city: { type: String },
countryCode: { type: String },
postalCode: { type: String },
userType: { type: String, enum:['firms','drivers','both']},
approved: { type: Boolean },
isAdmin: { type: Boolean }
});
userSchema.plugin(uniqueValidator);
module.exports = mongoose.model("User", userSchema);
and documents model
const mongoose = require("mongoose");
const docsSchema = mongoose.Schema({
docsPath: { type: String, required: true },
creator: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
docType: { type: String, enum:['isr','lmp','pocmr'], required: true }
});
module.exports = mongoose.model("Docs", docsSchema);
I want to join collections so that for every user exists the user_docs field with docs data as in code below. I'm trying to do that with joining _id with creator as it is defined when creating a document
exports.getUsersAndDocs = (req, res, next) => {
const query = User.aggregate([
{
$lookup: {
from: "Docs",
localField: "_id",
foreignField: "creator",
as: "user_docs"
}
}]);
query
.then(fetchedUsers => {
res.status(200).json({
message: "Users fetched successfully!",
users: fetchedUsers,
});
})
.catch(error => {
res.status(500).json({
message: "Fetching users failed!"
});
});
};
I'm recieveing empty user_docs array. Thank you for your help
If someone has the same problem. I solved it by changing
from: "Docs"
to
from: Docs.collection.name
There is a schema of homeworks:
const schema = new Schema({
dateAssign: { type: Date, default: Date.now, index: true },
teacher: { type: Schema.ObjectId, ref: 'user', index: true },
lesson: { type: Schema.ObjectId, ref: 'lesson', index: true },
exercises: [
{ type: Schema.ObjectId, ref: 'exercise' },
],
});
mongoose.model('homework', schema)
An exercise's schema:
const schema = new Schema({
block: { type: Schema.ObjectId, ref: 'lessonblock', index: true },
variant: { type: Schema.ObjectId, ref: 'variant', index: true },
result: { type: Schema.ObjectId, ref: 'exerciseresult', index: true },
variables: { type: Schema.Types.Mixed, default: {} },
start_at: { type: Date },
lock: { type: Boolean, default: false, index: true },
});
mongoose.model('exercise', schema);
How to find all homeworks where in exercises all elements has a field 'lock' = true?
I have tried, but it didn't work:
const HWs = await Homework.find({ teacher, 'exercises.lock': true }, null, { sort: { dateAssign: -1 }, limit: 20 })