简体   繁体   中英

Undesirable structure when populating sub document with Mongoose

A user has project IDs but I also want to store some additional project info:

const userSchema = new Schema({
...
  projects: [{
    _id: {
      type: Schema.Types.ObjectId,
      ref: 'Project',
      unique: true, // needed?
    },
    selectedLanguage: String,
  }]
});

And I want to populate with the project name so I'm doing:

const user = await User
  .findById(req.user.id, 'projects')
  .populate('projects._id', 'name')
  .exec();

However user.projects gives me this undesirable output:

[
  {
    selectedLanguage: 'en',
    _id: { name: 'ProjectName', _id: 5a50ccde03c2d1f5a07e0ff3 }
  }
]

What I wanted was:

[
  { name: 'ProjectName', _id: 5a50ccde03c2d1f5a07e0ff3, selectedLanguage: 'en' }
]

I can transform the data but I'm hoping that Mongoose can achieve this out the box as it seems a common scenario? Thanks.

尝试这样的populate({path:'projects', select:'name selectedLanguage'})

Seems like there are two options here:

1) Name the _id field something more semantic so it's:

{
  selectedLanguage: 'en',
  somethingSemantic: { _id: x, name: 'ProjectName' },
}

2) Flatten the data which can be done generically with modern JS:

const user = await User
  .findById(req.user.id, 'projects')
  .populate('projects._id', 'name')
  .lean() // Important to use .lean() or you get mongoose props spread in
  .exec();

const projects = user.projects.map(({ _id, ...other }) => ({
  ..._id,
  ...other,
}));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM