How to fetch post (show if followType is free hide premium posts) of my following using aggreate mongodb Nestjs? - mongodb

My USER Model:
This is My user Schema:
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import mongoose, { Document } from 'mongoose';
export type UserDocument = User & Document;
export enum FollowerType {
SIMPS = 'SIMPS',
FOLLIES = 'FOLLIES',
}
#Schema({ timestamps: true })
export class User {
#Prop({
type: String,
trim: true,
unique: true,
required: true,
lowercase: true,
})
username: string;
#Prop({
type: String,
trim: true,
unique: true,
required: true,
lowercase: true,
})
email: string;
#Prop({
type: String,
required: true,
})
password: string;
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
unique: true,
},
])
userReportedBy?: User[];
#Prop([
{
followedType: {
type: String,
enum: FollowerType,
},
user: { type: mongoose.Schema.Types.ObjectId, ref: User.name },
},
])
following: [
{
followedType: string;
user: User;
},
];
#Prop([
{
followedType: {
type: String,
enum: FollowerType,
},
user: { type: mongoose.Schema.Types.ObjectId, ref: User.name },
},
])
followedBy: [
{
followedType: string;
user: User;
},
];
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
unique: true,
},
])
blockedBy: User[];
#Prop({ type: String })
profilePic?: string;
#Prop({ type: Boolean, default: false })
isUserSuspended: boolean;
#Prop({ type: Boolean, default: false, required: true })
verified: boolean;
#Prop({ type: Boolean, default: false, required: true })
isDeleted: boolean;
#Prop({ type: Date, require: false })
deletedAt: Date;
}
export const UserSchema = SchemaFactory.createForClass(User);
POST MODEL:
This is My Post Model
/* eslint-disable prettier/prettier */
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import mongoose, { Document } from 'mongoose';
import { User } from './User.model';
export type PostDocument = Posts & Document;
#Schema({ timestamps: true })
export class Posts {
#Prop({
type: String,
})
media: string;
#Prop({
type: String,
enum: ['video', 'audio', 'image'],
})
mediaType: string;
#Prop({
type: String,
})
description: string;
#Prop({ type: Boolean, default: false, required: true })
isPremium: boolean;
#Prop({
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
})
userId: User;
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
unique: true,
},
])
userTagged?: User[];
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
},
])
userLike?: User[];
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
},
])
userDislike: User[];
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
},
])
userSeen: User[];
#Prop([
{
type: mongoose.Schema.Types.ObjectId,
ref: User.name,
},
])
userReported: User[];
#Prop({ type: Boolean, default: false })
ispostSuspended: boolean;
#Prop({ type: Date, required: false })
deletedAt?: Date;
}
export const PostSchema = SchemaFactory.createForClass(Posts);
Trying to fetch Posts of my following users according to type by checking whether user is blocked or not.
Expected Result
Result:[
{
userId:'dsjfksdkjfasd7dfsdf',
username:'test123',
posts:[
{
media:'htttps://djkfskjdf.com',
postId:'sdhfkjdfkhkjfd',
}
]
}
]

Related

mongoose validator not working as expected

i want to add batch,department,stream,id fields to the schema depending if usertype is “Student”,i do not understand why,but sometimes it adds the fields sometimes not.forexample if i created a user with usertype “Student” first it does not add the fields,but after that when i created a user with usertype “Teacher” or “Admin” it asks me the fields are required meaning it add the fields and this happens vice versa.why any way to fix this issue?please help guys.
what i have tried well,i have asked chatGpt but no answers i mean just the answers do not solve the issue.
here is the code
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
fullName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
userType: {
type: String,
required: true,
},
phoneNumber: { type: String, required: true },
password: { type: String, required: true },
approved: { type: Boolean, default: true },
},
{
timestamps: true,
}
);
userSchema.pre("validate", function (next) {
if (this.userType === "Student") {
this.constructor.schema.add({
batch: {
type: Number,
required: true,
},
department: {
type: String,
required: true,
},
stream: {
type: String,
required: true,
},
id: { type: String, required: true }, //, unique: true
});
}
next();
});
const userModel = mongoose.model("users", userSchema);
module.exports = userModel;

Mongodb mongoose join two collection and fetch data

schema:
var UserSchema = new Schema({
id: { type: String, unique: true },
username: { type: String, unique: true },
password: String,
first_name: String,
last_name: String,
email: { type: String, unique: true },
phone: { type: String, unique: true },
status: { type: Boolean, default: false },
role: {
type: String,
enum: ["REGULAR", "ADMIN", "SUPER-ADMIN", "OPERATOR"],
default: "REGULAR",
},
tenantRef: { type: Schema.Types.String, ref: "tenant" },
teamRef: { type: Schema.Types.String, ref: "team" },
customerRef: { type: Schema.Types.String, ref: "customer" },
created: { type: Date, default: Date.now },
});
var CustomerSchema = new Schema({
id: { type: String, unique: true },
name: String,
plan: String,
billing: String,
status: { type: Boolean, default: true },
created: { type: Date, default: Date.now },
});
controller:
userController.getUsers = async function (req, res) {
const users = await UserSchema.find({}).populate({
path: "teamRef",
});
console.log(users);
return res.status(200).send(users);
};
Here i am trying to join user and customer so that i can get customer name along with user data .
I am using above way but it is not working.
Please take a look how can i do it

How to type array of mongoose ObjectID in typescript

I'am having an issue with the typing in TypeScript and mongoose schema.
I have the following model for a user :
export interface IUser extends mongoose.Document {
firstname: string;
lastname: string;
email: string;
password?: string;
lang: string;
color: string;
roles: IRole[];
labs: ILab[];
}
export const UserSchema = new mongoose.Schema({
firstname: {
type: String,
required: [true, 'Firstname required']
},
lastname: {
type: String,
required: [true, 'Lastname required']
},
email: {
type: String,
required: [true, 'Email required']
},
password: {
type: String,
required: [true, 'Password required']
},
lang: {
type: String,
required: [true, 'Lang required']
},
color: {
type: String,
required: [true, 'Color required']
},
roles: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Role'
}
],
labs: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Lab'
}
]
});
The thing is that i want to do a query to retrieve all the users that match a specific lab ID so I mad this :
User.find({ labs: { $in: req.params.id } })
But I have an error with typecript because the find is actually on ObjectId array, but in the interface relate to ILab[].
The only way i found is to make the query as Any but as you may know it is not ideal to use any.
Would be nice if anyone have a hint on that ?
Maybe just:
import { Schema } from "mongoose";
interface IUser extends mongoose.Document {
...
labs: [{ type: mongoose.Schema.Types.ObjectId, ref: "Lab" }];
}
I had the same problem and I fixed it this way.

Mongoose populate method on query returns empty array

I am having trouble querying my model, and using the .populate method to grab referenced documents of my object. Here are my schemas:
var userSchema = new Schema({
firstname: { type: String, required: true, unique: false },
lastname: { type: String, required: true, unique: false },
...
children: [{type: mongoose.Schema.Types.ObjectId, ref: 'Child'}],
});
var childSchema = new Schema({
firstname: { type: String, required: true, unique: false },
lastname: { type: String, required: true, unique: false },
...
legal_guardian_id: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}],
});
And here is how i'm trying to run my query:
User.findOne({ _id: '5b9d30083e33585cc0b8c710' })
.populate('children').exec((err, doc) => {
if (err) { return console.error(err); }
res.send(doc);
})
This results in "children": []
When I just use the findOne method and return the user, I get "children":["5b9d3f23d1408c5f4e2624f3"].
What am I doing wrong?

Mongoose: How can I reference a nested schema that is in a separate file?

If two schemas are in the same file, you can reference it with: [AccountSchema]. You can see that in the "accounts" property of the UserSchema.
import express from 'express'
import mongoose from 'mongoose'
const Schema = mongoose.Schema
import Account from './accounts'
let AccountSchema = new Schema ({
accountName: {
type: String,
trim: true,
required: true,
unique: [true, "You already have an account with this name."],
},
percent: {
type: Number,
min: 1,
max: 100,
required: true
},
isGoal: {
type: Boolean,
default: false
},
accountHistory: {
type: Array
}
})
let UserSchema = new Schema ({
username: {
type: String,
unique: [true, "This username is taken."],
trim: true,
},
email: {
type: String,
unique: [true, "This email is already being used."],
trim: true
},
password: {
type: String,
trim: true
},
infusions: {
type: Array,
timestamps: true
},
accounts: {
type: [AccountSchema],
count: {
type: Number,
default: 8
}
},
secretToken: {
type: String
},
active: {
type: Boolean,
default: false
},
isAdmin: {
type: Boolean,
default: false
}
}, {
timestamps: true,
})
const User = mongoose.model('users', UserSchema)
export default User
But what do you do if the schemas are in separate files? How can you reference them? I tried like this, but it didn't work:
// account.js
import express from 'express'
import mongoose from 'mongoose'
const Schema = mongoose.Schema
let AccountSchema = new Schema ({
accountName: {
type: String,
trim: true,
required: true,
unique: [true, "You already have an account with this name."],
},
percent: {
type: Number,
min: 1,
max: 100,
required: true
},
isGoal: {
type: Boolean,
default: false
},
accountHistory: {
type: Array
}
})
const Account = mongoose.model('users', AccountSchema)
export default Account
And the User schema in a separate file with:
// users.js
import express from 'express'
import mongoose from 'mongoose'
const Schema = mongoose.Schema
import Account from './accounts'
let UserSchema = new Schema ({
username: {
type: String,
unique: [true, "This username is taken."],
trim: true,
},
email: {
type: String,
unique: [true, "This email is already being used."],
trim: true
},
password: {
type: String,
trim: true
},
infusions: {
type: Array,
timestamps: true
},
accounts: {
type: [Account],
count: {
type: Number,
default: 8
}
},
secretToken: {
type: String
},
active: {
type: Boolean,
default: false
},
isAdmin: {
type: Boolean,
default: false
}
}, {
timestamps: true,
})
const User = mongoose.model('users', UserSchema)
export default User
In one article I was told to export the schema, not the model that references the schema, but they did not give any idea as to how to achieve that.
Try removing below line from your account.js file
const Account = mongoose.model('users', AccountSchema);
And change the last line to this
export default AccountSchema;