Mongodb select 'field' with condition in Query Population - mongodb

Let's say that I have three entities Track, Chapter and Episode, a track can contain one or more chapters, a chapter is associated with one track and can contain zero or more episodes.
Track.ts :
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
import * as mongoose from 'mongoose';
import { Chapter } from './chapter.entity';
#Schema({
timestamps: true,
})
export class Track extends Document {
...
#Prop({
type: [mongoose.Schema.Types.ObjectId],
ref: 'Chapter',
})
chapters: [Chapter];
}
export const TrackSchema = SchemaFactory.createForClass(Track);
Chapter.ts :
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
import * as mongoose from 'mongoose';
import { Track } from './track.entity';
import { Episode } from './episode.entity';
#Schema({
timestamps: true,
})
export class Chapter extends Document {
...
#Prop({
type: mongoose.Schema.Types.ObjectId,
ref: 'Track',
required: true,
})
track: Track;
#Prop({
type: [mongoose.Schema.Types.ObjectId],
ref: 'Episode',
})
episodes: [Episode];
}
export const ChapterSchema = SchemaFactory.createForClass(Chapter);
What I want is to find a "track" and populate its "chapters" but without selecting the field "episodes" if it is an empty array. I was looking in the docs I found out how to populate documents with condition but nothing about fields, I found out also how to select some fiels but not with condition.
var track = await this.trackModel
.findById(id)
.populate({
path: 'chapters',
select: '-episodes', // this excludes the episodes field, how can I do it with condition
})
.lean();
Thank you for your attention!

Related

NestJS and mongo two way relation between post schema and user schema

I am new to nest and mongo I am trying to do a relation where a user schema embeds a posts array with ids of posts and in the posts schema I want to embed the author which is a user schema with the user id but I keep running into this error in my console
Error: Cannot determine a type for the "Post.author" field (union/intersection/ambiguous type was used). Make sure your property is decorated with a "#Prop({ type: TYPE_HERE })" decorator.
this is my code
UserSchema
import { Prop, Schema, SchemaFactory } from "#nestjs/mongoose";
import { Document } from "mongoose";
import { Post, PostSchema } from "src/posts/entities/post.entity";
export type UserDocument = User & Document;
#Schema()
export class User extends Document{
#Prop({ index: true})
name: string;
#Prop([{ type: PostSchema}])
posts: Post[]
}
export const UserSchema = SchemaFactory.createForClass(User)
PostSchema
import { Prop, Schema, SchemaFactory } from "#nestjs/mongoose";
import { Document } from "mongoose";
import { User, UserSchema } from "src/users/entities/user.entity";
export type PostDocument = Post & Document;
#Schema()
export class Post extends Document{
#Prop({index: true})
title: string;
#Prop({index:true})
body: string;
#Prop({type: UserSchema})
author: User;
}
export const PostSchema = SchemaFactory.createForClass(Post)
at the end what I am trying to achive in my database is this
users collection
{
"_id" : "U1",
"name":"user1",
"posts": [
{
"_id": "P1",
"title":"title 1",
"body":"body 1"
}
]
}
posts collection
{
"_id" : "P1",
"title":"title 1",
"body":"body 1",
"author": {
"_id": "U1",
"name":"user1",
}
}
I am trying to embed doucments into each other with the ids so I can read fast and use the ids to update
your user schema have a problem.
the way you define an array is wrong. use this one :
#Prop({type: [PostSchema]})
posts: Post[]

Schema.name undefined while making Many-To-One relation reference with Nestjs & MongoDb

I want to attach and see all the posts of the user inside posts property of UserSchema. The user/Author id is getting stored with posts. But when I try the get posts ids
I'm getting the following error.
#Prop([{ type: mongoose.Schema.Types.ObjectId, ref: BlogPost.name }])
^
TypeError: Cannot read properties of undefined (reading 'name')
at Object.<anonymous> (D:\Noum\Data\CYBRNODE\MAN STACK\Cybrnode-Blog-Backend\Cybr-Blog-Nest-Backend\src\schema\user.schema.ts:45:64)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
Blog Schema
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { ApiProperty } from '#nestjs/swagger';
import mongoose, { Document } from 'mongoose';
import { User } from 'src/schema/user.schema';
#Schema({ timestamps: true })
export class BlogPost {
#ApiProperty({ required: true })
#Prop({ type: mongoose.Schema.Types.ObjectId, ref: User.name })
author: User;
}
export const postSchema = SchemaFactory.createForClass(BlogPost);
export type postDocument = BlogPost & Document;
User Schema
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { ApiProperty } from '#nestjs/swagger';
import mongoose, { Document } from 'mongoose';
import { BlogPost } from 'src/schema/blog.schema';
#Schema({ timestamps: true })
export class User {
#ApiProperty()
#Prop([{ type: mongoose.Schema.Types.ObjectId, ref: BlogPost.name }])
posts: BlogPost[];
}
export const userSchema = SchemaFactory.createForClass(User);
export type userDocument = User & Document;
Also I've imported UserModule into BlogPostModule and vice versa. And exported the services of both modules.
I've tried with these as well. But Error is same
import { Document, Schema as MongooseSchema } from 'mongoose';
export class User extends Document{
#ApiProperty()
#Prop([{ type: MongooseSchema.Types.ObjectId, ref: BlogPost.name }])
posts: BlogPost[];
}
export const userSchema = SchemaFactory.createForClass(User);
export type userDocument = User & Document;

How to populate Nestjs mongoose schema records

I want to get then enteries from paris air quality, but the thing is that the mongoose schema is nested and I tried to make multiple schemas separated but I don't know wheter it's correct or not.
This is the schema file schemas/air-quality.schema.ts
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
export type AirQualityDocument = AirQuality & Document;
#Schema()
export class Pollution {
#Prop()
ts: string;
#Prop()
aqius: number;
#Prop()
mainus: string;
#Prop()
aqicn: number;
#Prop()
maincn: string;
}
#Schema()
export class Result {
#Prop({ type: Pollution })
pollution: Pollution;
}
#Schema()
export class AirQuality {
#Prop({ type: Result })
result: Result;
#Prop()
datetime: string;
}
export const AirQualitySchema = SchemaFactory.createForClass(AirQuality);
And the result I am getting from mongo is this
PS: it contains multiple entries of the same schema
[
{
"_id": "62dd1b2e744e6bf8cdbcfabd",
"result": {
"_id": "62dd1b2e744e6bf8cdbcfabe"
},
"datetime": "24/07/2022, 11:13:02",
"__v": 0
},
...
]
I don't if the mistake is with the schema or I just need to use autopopulate or something

MissingSchemaError in Nestjs

hello everyone i'm not able specify relation to another model. when i add a relation it's showing me this error
Book Model
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
export type BookDocument = Book & Document;
#Schema({ timestamps: true, collection: 'books' })
export class Book {
#Prop({ type: String, required: true })
name: string;
#Prop({ type: String, required: true })
author: string;
#Prop({ type: String, required: true })
bookType: string;
}
export const BooksSchema = SchemaFactory.createForClass(Book);
BookLend Model
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Schema as mongooseSchema, Document } from 'mongoose';
import { Book } from '../../books/enitiy/book.model';
import { IsNotEmpty } from 'class-validator';
export type BookLendDocument = BookLend & Document;
#Schema({ timestamps: true })
export class BookLend {
#IsNotEmpty()
#Prop({ type: mongooseSchema.Types.ObjectId, ref: 'books', required: true })
bookId: Book;
#IsNotEmpty()
#Prop({ type: String, required: true })
name: string;
#IsNotEmpty()
#Prop({ type: String, required: true })
returnDate: string;
#Prop({ type: String })
returnedOn: string;
#IsNotEmpty()
#Prop({ type: String, required: true })
status: string;
}
export const BookLendSchema = SchemaFactory.createForClass(BookLend);
i'm referring the books objectID to booklend booksID , when i use below code i'm getting error MissingSchemaError: Schema hasn't been registered for model "books".
const allBookLendDetails = await this.bookLend
.find()
.populate('bookId')
.exec();
hi guy's I fixed it by importing the BooksSchema into BookLend Module file
here ref code:-
import { Module } from '#nestjs/common';
import { BookLendService } from './book-lend.service';
import { BookLendController } from './book-lend.controller';
import { MongooseModule } from '#nestjs/mongoose';
import { BookLendSchema } from './entities/book-lend.entity';
import { CommonService } from '../common-service/common-service.service';
import { BooksSchema } from '../books/enitiy/book.model';
#Module({
imports: [
MongooseModule.forFeature([
{ name: 'booklend', schema: BookLendSchema },
{ name: 'books', schema: BooksSchema },
]),
],
controllers: [BookLendController],
providers: [BookLendService, CommonService],
})
export class BookLendModule {}
In the service file, you need to inject the model
constructor(
#InjectModel('booklend') private readonly bookLend: Model<BookLend>,
#InjectModel('books') private readonly books: Model<Book>
) {}

How to create mongoose schema for category sub category management?

MongoDB Schema for handling category subcategory management where you can have multiple of subcategories from one root category. Basically for e-commerce system where user can add a product by selecting a category.
I have some requirements like:
Fast retrieval of data from DB and easy insertion.
Please change according to you
import mongoose from 'mongoose';
const {Schema} = mongoose;
import slug from 'slug';
import shortid from 'shortid';
const categorySchema = new Schema({
slug: {
type: String,
required: true,
unique: true,
},
isDelete: {
type: Boolean,
default: false
},
}, {
timestamps: true
});
categorySchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
categorySchema.methods.slugify = function () {
this.slug = slug(this.firstName) + '-' + shortid.generate();
};
export default mongoose.model('category', categorySchema);
Please don't send any link to mongoDb docs