From 321e00396a10e6a51987c62fe53e844c6d1c27c5 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Mon, 17 Oct 2022 11:12:06 +0200 Subject: [PATCH] docs(populate): added transform option description --- docs/populate.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/populate.md b/docs/populate.md index 1af084bea04..fd80233d86f 100644 --- a/docs/populate.md +++ b/docs/populate.md @@ -56,6 +56,7 @@ user and have a good reason for doing so.
  • Populating Maps
  • Populate in Middleware
  • Populating Multiple Paths in Middleware
  • +
  • Manipulate populated objects
  • Saving refs

    @@ -878,3 +879,50 @@ userSchema.pre('find', function (next) { }); ``` Alternatively, you can check out the [mongoose-autopopulate plugin](http://npmjs.com/package/mongoose-autopopulate). + +

    Manipulate populated objects

    + +We can manipulate populated objects using `transform`. This option lets you register a function with two arguments: the populated document, and the original id, used to populate the document. The function will be called on every populated document and will give us more control over the result of the `populate()` execution. + +The [original motivation](https://github.com/Automattic/mongoose/issues/3775) for the `transform` option was to give the ability to leave the unpopulated `_id` if no document was found, instead of setting the value to `null`: + +```javascript +// Without `transform` +doc = await Parent.findById(doc).populate([ + 'child', + // Set `retainNullValues` to true to keep `null` values + { path: 'children', options: { retainNullValues: true } } +]); + +doc.child; // null +doc.children; // [ null, { _id: 634d1a4ddb804d17d95d1c7f, name: 'Luke', __v: 0 } ] + +// With `transform` +doc = await Parent.findById(doc).populate([ + { + path: 'child', + transform: (doc, id) => doc == null ? id : doc + }, + { + path: 'children', + options: { retainNullValues: true }, + transform: (doc, id) => doc == null ? id : doc + } +]); + +doc.child; // 634d1a5744efe65ae09142f9 +doc.children; // [ 634d1a67ac15090a0ca6c0ea, { _id: 634d1a4ddb804d17d95d1c7f, name: 'Luke', __v: 0 } ] +``` + +Further more, we can also use `transform` to flatten the returned documents: + +```javascript +let doc = await Parent.create({ children: [ { name: 'Luke' }, { name: 'Leia' } ] }); + +doc = await Parent.findById(doc).populate([{ + path: 'children', + transform: doc => doc == null ? null : doc.name +}]); + +doc.children; // ['Luke', 'Leia'] +``` \ No newline at end of file