Query multiple collections Nodejs - node.js

Hello im trying to join these collections i want to get all users which has "active" attribute equal to false. I couldn't figure out how to acquire this query. There are my schemas:
User Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
type: {
type: String,
required: true
},
active:{
type:Boolean
}
});
module.exports = mongoose.model('users', UserSchema);
Company Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CompanySchema = new Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
companies: [{
name: {
type:String
},
country:{
type:String
}
}
]
});
module.exports = Company = mongoose.model('company', CompanySchema);
Note: Not all users have companies only the type "client" and i want to get both, "client" and "employe"

You may want to refactor your Schema to better accommodate the type of data you have available.
For example:
User Schema:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
type: {
type: String,
required: true
},
active:{
type:Boolean
},
companies: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'company'
}]
});
And Company Schema:
const CompanySchema = new Schema({
name: {
type:String
},
country:{
type:String
}
});
Then to get a list of all users who are active, and automatically populate any company data for those users (Assuming your user model is called UserModel)
UserModel.find({ active: false }).populate('companies').exec();
If you are unable to edit your data structure for any reason, then you could perform a query similar to:
CompanyModel.aggregate([
{ $lookup: { from: 'users', localField: 'userId', foreignField: '_id', as: 'user' } },
{ $match: { '$user.active': false } }
]).exec()
This will perform an aggregate lookup on the UserId field and then only match on ones where the active property is set to false.

Related

How do I fetch User post on user timeline?

I have a database containing 3 collections [Users (contains registered users), Userpost (contains the post of the registered users) while Profile (contains their individual profile)].
I was able to link the Profile and Users Schemas to the Userpost Schema with their ObjectId.
What I know at present is how to fetch the Userpost and populate the User and Profile.
What I want to do is to fetch all the post of a single registered user his/her timeline.
What I have tried to the add the Userpost and Profile Schemas to the UserSchema by the ObjectId but each time I make a post, the Userpost on the User collection is always an empty array.
Below are my Schemas please
User Schema
const userSchema = new Schema({
username: {
type: String,
required: true
},
roles: {
User: {
type: Number,
default: 2001
},
Mentor: Number,
Admin: Number
},
password: {
type: String,
required: true
},
userID: {
type: String,
required: true
},
refreshToken: String
});
const User = mongoose.model('user', userSchema);
module.exports = User;
Profile Schema
const ProfileSchema = new Schema({
lastname: {
type: String,
required: true,
},
firstname: {
type: String,
required: true,
},
othernames: {
type: String,
required: true,
},
countries: {
type: String,
required: true,
},
phones: {
type: String,
required: true,
},
User: [{
type: Schema.Types.ObjectId,
ref: 'user',
required: true,
}],
});
const Profile = mongoose.model('profile', ProfileSchema);
module.exports = Profile;
UserPost Schema
const UserpostSchema = new Schema({
post: {
type: String,
required: true
},
Profile: [{
type: Schema.Types.ObjectId,
ref: 'profile',
required: true,
}],
User: [{
type: Schema.Types.ObjectId,
ref: 'user',
required: true,
}]
});
const Userpost = mongoose.model('userpost', UserpostSchema);
module.exports = Userpost;
How I populate User and Profile to the UserPost on API
router.get('/getpost/:id', (req, res) => {
const id = req.params.id;
Userpost.find({_id:id}).populate('User').populate('Profile').exec((err,docs) => {
if(err) throw(err);
res.json(docs);
})
});
How do I fetch the entire post of a user to his timeline?
Kindly help please.
Thanks and regards
This should work for u, In UserPost Schema you have taken array for Profile and User which isn't required, and also instead of Schema use mongoose.Schema every where in model.
User Schema
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true
},
roles: {
User: {
type: Number,
default: 2001
},
Mentor: Number,
Admin: Number
},
password: {
type: String,
required: true
},
userID: {
type: String,
required: true
},
refreshToken: String
});
const User = mongoose.model('user', userSchema);
module.exports = User;
Profile Schema
const mongoose = require("mongoose");
const ProfileSchema = new mongoose.Schema({
lastname: {
type: String,
required: true,
},
firstname: {
type: String,
required: true,
},
othernames: {
type: String,
required: true,
},
countries: {
type: String,
required: true,
},
phones: {
type: String,
required: true,
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
required: true,
},
});
const Profile = mongoose.model('profile', ProfileSchema);
module.exports = Profile;
UserPost Schema
const mongoose = require("mongoose");
const UserpostSchema = new mongoose.Schema({
post: {
type: String,
required: true,
},
Profile: {
type: mongoose.Schema.Types.ObjectId,
ref: "profile",
required: true,
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
required: true,
},
});
const Userpost = mongoose.model("userpost", UserpostSchema);
module.exports = Userpost;

How to populate a data for a field in mongoose, where reference is a nested array in model?

How can I populate category in courses model?
I have courses, courses will have category from categories->subcategories model.
I don't know how to populate from nested objects.
Reference model is category, I have to populate from array subcategories!
**courses:**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'category'
}
});
**category:**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [{
name: {
type: String
}
}]
});
const Category = mongoose.model('category', CategorySchema);
module.exports = Category;
use seprate collection for subCetagory like:
**courses**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'SubCategory'
}
});
**SubCategory:**
const mongoose = require("mongoose");
const SubCategorySchema = new mongoose.Schema({
name: {
type: String,
required: true
},
categorie: {
type: String,
ref: "category"
}
});
const SubCategory = mongoose.model('category', SubCategorySchema);
module.exports = SubCategory;
**Category**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [
{
type: Schema.types.objectId,
ref: "SubCategory"
}
]
});
then just add subcetagory id to course when insert new course or update a course and when you want to get course along with subcetagory and category use populate query of mongoose

How can i display products per each category stored in MongoDB

currently i created a schema for storing products using mongoose as below
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
title: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
description: {
type: String,
required: true
},
quantity: {
type: Number,
required: true
},
manufacture: {
type: String,
required: true
},
creator: {
type: Schema.Types.ObjectId,
ref: 'user'
},
category: {
type: Schema.Types.ObjectId,
ref: 'category'
}
});
module.exports = { Product: mongoose.model('product', ProductSchema) };
and here another schema for storing categories that products are related to
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CategorySchema = new Schema({
title: {
type: String,
required: true
}
});
module.exports = { Category: mongoose.model('category', CategorySchema) };
each product is related to a category
the question is how can i display all products that are related to a specific category.
i tried .find() method but i can't use it correctly.
thanks for any advice
You need to use .populate('category'), after .find() in order to populate all the connected data.
products.find().populate('category').exec((err, product) => { })

mongoose schema , Invalid schema configuration

i have a schema of user that contain an array of movie
i create a new schema of Movie
but i get error of invalid schema configuration.
what i'm doning worng?
enter code here
const mongoose = require("mongoose");
const Movie = require("./movie-model");
const Schema = mongoose.Schema;
const User = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
movies: { type: Movie },
});
module.exports = mongoose.model("user", User);
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var Movie = new Schema(
{
name: { type: String, required: true },
time: { type: String, required: true },
rating: { type: Number, required: false },
priorety: { type: Number, required: true },
},
);
module.exports = mongoose.model("movie", Movie);
in movie-model
module.export = Movie
instead of
module.exports = mongoose.model("movie", Movie);
User has many movies
const mongoose = require("mongoose");
const Movie = require("./movie-model");
const Schema = mongoose.Schema;
const User = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
movies: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "movie",
},
],
});
module.exports = mongoose.model("user", User);
I invite you to read more about One-to-Many Relationships with Embedded Documents
You need to done referencing in User collection
movies: [
type: mongoose.Schema.ObjectId,
ref: 'user'
]
//instead of doing that
movies: { type: Movie },

Is there a way to pass user Id to schema?

I have a user schema and an exam schema, i wanted to pass the id of the user to the schema of the exam
const ExamSchema = new mongoose.Schema({
-----> _id: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
Where it says _id - i wanted it to be the id of the user! Should i do it like this or add the exams schema on the user schema? Like this?
const UserSchema = new mongoose.Schema({
username: { type: String, require: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
active: { type: Boolean, default: true },
exam: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
});
Check Mongoose "Populate"
https://mongoosejs.com/docs/populate.html
A part from the docs,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
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);
So far we've created two Models. Our Person model has its stories field set to an array of ObjectIds. The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _ids we store here must be document _ids from the Story model.
In your case just make a user_id in Exam Schema and refer to id of User Schema
const ExamSchema = new mongoose.Schema({
user_id: {type: Schema.Types.ObjectId, ref: 'User' },
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
})

Resources