Search code examples
javascriptmongoosenestjsnestjs-mongoose

Can't query with condition on relation nestjs/mongoose


I have an Item model, and a Category Model.
The item model has a reference (ObjectId) to the Category model.
I am writing code to get the items in a specific category.
So i get the id of the category as a paremeter(of type string) to the service,
then write "return this.ItemModel.find({category: id}).exec();".
where 'category' is the reference to the Category model,
and 'id' is the id passed to the API call.
I get the error "No Overload Matches This Call".

How can i solve this?

Item Schema

export type ItemDocument = Item & Document;
@Schema({ timestamps: true })
export class Item {
  @Prop()
  name_en: string;
  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Category' })
  category: Category;
}
export const ItemSchema = SchemaFactory.createForClass(Item);

Category Schema

export type CategoryDocument = Category & mongoose.Document;
@Schema({ timestamps: true })
export class Category {
  @Prop()
  name_en: string;
}
export const CategorySchema = SchemaFactory.createForClass(Category);

category.service.ts

@Injectable()
export class CategoryService {
  constructor(
    @InjectModel(Category.name)
    private categoryModel: mongoose.Model<CategoryDocument>,
    @InjectModel(Item.name)
    private readonly ItemModel: mongoose.Model<ItemDocument>,
  ) {}
  findOneCatItems(id: string) {
    return this.ItemModel.find({category: id}).exec(); --> Error Line
  }
}

Solution

  • You mentioned here

    The item model has a reference (ObjectId) to the Category model.

    but the category property of the Item model is typed as a Category.

    When you do this: this.ItemModel.find({category: id}).exec();

    You are providing a type of ObjectId where a type of Category is expected.

    Since you are not saving the entire category object on an item, change the definition in your Item class to:

    @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Category' })
      category: mongoose.Schema.Types.ObjectId;
    

    Note: if you are passing id as a string here this.ItemModel.find({category: id}).exec();, Then typing category as a string instead of ObjectId will work