javascripttypescriptmongoosenosqlnestjs

NestJs mongoose nested populate not working as expected


I tried every possible syntax to figure out how to populate data in mongoose, but none is working, this is my example :

  1. each Customer has an array of Persons
  2. Each person has an address
  3. also each Customer has one Address I want to populate the customer along with the persons and their address. it only returns the persons's data but without the address data.

I tried this :

 this._customerModel
.findOne({ _id: '60898b500870d6a664fc7403' })
.populate({ path: 'persons', populate: { path: 'persons.address' } });

and this :

 this._customerModel
.findOne({ _id: '60898b500870d6a664fc7403' })
.populate({ path: 'persons' });

and this :

 this._customerModel
.findOne({ _id: '60898b500870d6a664fc7403' })
.populate({ path: 'persons', model : 'Person' })

and this :

 this._customerModel
.findOne({ _id: '60898b500870d6a664fc7403' })
.populate('persons');

they all return this :

{
  address: 60898b500870d6a664fc7404,
  persons: [],
  _id: 60898b500870d6a664fc7403,
  siren: 'string',
  companyName: 'string',
  legalForm: 'string',
  startDate: 'string',
  __v: 0
}

as you can see it doesn't even return the IDs inside persons. if I don't populate anything, it returns this :

{
  address: 60898b500870d6a664fc7404,
  persons: [ 60898b500870d6a664fc7405, 60898b500870d6a664fc7408 ],
  _id: 60898b500870d6a664fc7403,
  siren: 'string',
  companyName: 'string',
  legalForm: 'string',
  startDate: 'string',
  __v: 0
}

the data is there as you can see. it's actually the same thing for address. it doesn't get populated it's always the ObjectId what gets returned. I'm injecting the Models like this :

  MongooseModule.forFeature(
            [
                {
                    name: 'Customer',
                    schema: customerSchema,
                    collection: 'customers',
                },
            ],
            'nosql',
        )

I looked the internet. there is no example with 3 levels of nested populate() in NestJs if there's is one there or you might know the solution I'll be grateful if you let me know, thank you.

@Schema()
export class Customer extends mongoose.Document {
@Prop()
id: string;
@Prop({ type: String })
companyName: string;
@Prop({ type: { type: mongoose.Schema.Types.ObjectId, ref: 'Address' } })
address: Address;
@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Person' }] })
persons: Person[];
}

@Schema()
export class Person extends mongoose.Document {
@Prop()
id: string;
@Prop({ type: String })
firstName: string;
@Prop({ type: { type: mongoose.Schema.Types.ObjectId, ref: 'Customer' } })
customer: Customer;
@Prop({ type: { type: mongoose.Schema.Types.ObjectId, ref: 'Address' } })
address: Address;
}


@Schema()
export class Address extends mongoose.Document {
@Prop()
id: string;
@Prop({ type: String })
address1: string;
}

Update : this

this._customerModel
            .findOne({ _id: '60898b500870d6a664fc7403' })
            .populate('address')
            .populate('persons')

returns this :

{
  address: 60898b500870d6a664fc7404,
  persons: [
    {
      customer: 60898b500870d6a664fc7403,
      _id: 60898b500870d6a664fc7405,
      firstName: 'string',
      __v: 0
    },
    {
      address: 60898b500870d6a664fc7406,
      customer: 60898b500870d6a664fc7403,
      _id: 60898b500870d6a664fc7408,
      firstName: 'string',
      __v: 0
    }
  ],
  _id: 60898b500870d6a664fc7403,
  companyName: 'string',
}

still doesn't return the address (Level 1) nor the address under persons with any of my tries.


Solution

  • I found it after trying to make a git example, this is the problem :

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

    it should be like this :

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

    of course in the Array type also. I'm sorry internet.