Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.88k stars 3.83k forks source link

Automatically select populated fields #5669

Closed fernandobandeira closed 6 years ago

fernandobandeira commented 7 years ago

Do you want to request a feature or report a bug? feature What is the current behavior?

For a common products <=> categories relationship, given the following model:

const ProductSchema = new mongoose.Schema({
  name: {
    type: String,
  },
  categories: {
    type: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Category',
    }],
    select: false, // Notice that this is set to false
  },
});

I'm getting the following results:

Product.findById(id) // results in { name: 'Something' }

Product.findById(id)
  .populate('categories')
  // results in { name: 'Something' }

Product.findById(id)
  .select('+categories')
  .populate('categories')
  // results in { name: 'Something', categories: [{ name: 'Category' }]}

What is the expected behavior?

Product.findById(id)
  .populate('categories')
  // results in { name: 'Something', categories: [{ name: 'Category' }]}

I think we could select the categories field too, the dev should be able to overwrite this selection if he calls: select('-categories').

I'm using it like this since I don't want to send an array containing only id's since in my specific usecase this isn't an useful information and sometimes I might have ids of categories that doesn't exist anymore (were deleted) so I'd like to send this info only if it's been populated.

Another solution would be to add more values to the select option this way we could call select: 'populate' inside the Schema and achieve this behavior.

Please mention your node.js, mongoose and MongoDB version.

Node 8.4.0 MongoDB 3.4.7 Mongoose 4.10.8

vkarpov15 commented 7 years ago

This is a very good idea, thanks for the suggestion :+1:

xream commented 6 years ago

@vkarpov15 Hi, this may be a bug: https://github.com/Automattic/mongoose/commit/cc6e489766d3910150278b74b318f213c91f9c3d#diff-9338e093a001f8a5ef68472c3fcb4501R13

schema:

key: [{
  sub: { type: ObjectId, ref: 'Sub' },
  other: { type: String }
}]

query:

Test.find().select('key').populate([ { path: 'key.sub'} ])

result:

[{ key: [{ sub: {} }] }]

result should be:

[{ key: [{ sub: {}, other: '' }] }]

query._fields:

{ key: 1, 'key.sub': 1}

query._fields should be:

{ key: 1}
vkarpov15 commented 6 years ago

@xream thanks for reporting, that looks like a bug, will investigate.

vkarpov15 commented 6 years ago

@xream fixed, will be released with 4.12.2 :+1: