user1118374
user1118374

Reputation: 174

Mongoose findById is not returning all fields

I'm calling findById using mongoose and it's not returning all fields, or at least it's not mapping to a field correctly. But it returns that field if I use aggregate

I have the following schema

const ratingSchema = new mongoose.Schema({
    rating: {
        type: Number,
        default: 0,
        min: 0,
        max: 5
    }
})

const locationSchema = new mongoose.Schema({ 
    name: {
        type: String,
        required: true,
    },
    address: {
        type: String,
        required: true,
    },
    rating: ratingSchema,
    
    facilities: [String],
});

locationSchema.index({coords: '2dsphere'});

mongoose.model('Location', locationSchema);

When I call

const Loc = mongoose.model('Location');

const locationsReadOne = (req, res) => {
    Loc
        .findById(req.params.locationid)
        .exec((err, location) => {
            if (!location) {
                return res.status(404).json({"message":"location not found"});
            } else if (err) {
                return res.status(404).json(err);
            }
            console.log("locationsReadOne:",location);
            res.status(200).json(location);
        });
};

It returns the schema, but the rating field is not being returned. Here is a console.log of the returned object:

locationsReadOne: {
  facilities: [ 'Hot drinks', 'Food', 'Premium wifi' ],
  _id: 5f88bfdc4df4ca7709462865,
  name: 'Starcups',
  address: '125 High Street, Reading, RG6 1PS'
}

If I call Loc.aggregate, the rating field is returned:

{
  _id: 5f8b2ee15b0b6784a847b600,
  facilities: [ 'Tea', ' Restroom' ],
  name: 'Tea Leaf',
  address: '2192 Green St.',
  rating: 0,

}
{
  _id: 5f88bfdc4df4ca7709462865,
  name: 'Starcups',
  address: '125 High Street, Reading, RG6 1PS',
  rating: 3,
  facilities: [ 'Hot drinks', 'Food', 'Premium wifi' ]
}

Any idea why this would happen? I can clearly see the rating field in each of the documents in MongoDB compass and they are all listed as type Double. Why are they being returned in aggregate, but not in findById(id) or even in find()?

Thank you.

Upvotes: 3

Views: 1375

Answers (1)

AdamExchange
AdamExchange

Reputation: 1301

When you use find in mongoose, it will populate the document with the fields from the schema. For example - if you remove a field from the schema, you may not see that on the found document, even if it is in the database. Aggregate and Compass are showing you exactly what's in the database, so that data is there, it is just not being populated on the document because it doesn't see it on the schema.

The reason for that is your ratingSchema is an object with a rating property. So mongoose is looking for something like:

{
  name: ...
  rating: {
     rating: 2 
  }
}

And not finding it, so it's not populating. To fix this, I would not define rating as a subschema, and instead define your schema as

const locationSchema = new mongoose.Schema({ 
    name: {
        type: String,
        required: true,
    },
    address: {
        type: String,
        required: true,
    },
    rating: {
        type: Number,
        default: 0,
        min: 0,
        max: 5
    },   
    facilities: [String],
});

Upvotes: 3

Related Questions