There is a MyCollection
schema with:
...
author: {
type: mongoose.Schema.Types.ObjectId,
required: true, // the same with false
ref: 'Author'
},
...
And the code:
MyCollection
.find(filter, '_id author text')
.populate('author', '_id name')
.exec(),
If the document with author
was removed from Authors
collection, the populate method above throws the following error:
Cannot read properties of null (reading '_id')
The question is: How can populate() be configured to ignore removed ref's and simply return the document without the author
field?
I don't think ignoring removed refs is a good idea. It would be better to remove the ref if the subdocument author
has been deleted. The Mongoose default behaviour is to return null when there's no document, hence the error message you received. Mongoose provides you with two helper methods to check if the field is populated. You could try to incorporate:
// Returns a truthy value if author populated
MyCollection.populated('author');
// Make author not populated anymore
MyCollection.depopulate('author');
However, I would suggest you refactor your code so that when a document from author collection is deleted you pass the author._id
of the deleted document so that it can be pulled from the MyCollection
. Something like:
const deletedAuthor = await authorModel.findByIdAndDelete(authorid);
const myCollection = await myCollectionModel.findById(parentId);
myCollection.author.pull(authorid);
await myCollection.save();
Also, you don't need to include _id
in your .populate('author', '_id name')
projection because according to the docs the _id
field is returned as default on matching documents.
You can remove null fields after your query using basic JavaScript but you need to change exec()
to the lean()
method so that POJO are returned like so:
const myCollection = await MyCollection
.find(filter, '_id author text')
.populate('author', '_id name')
.lean();
const myCollectionFiltered = myCollection.map((doc)=>{
if(doc.author === null){
delete doc.author;
}
return doc;
});
Now myCollectionFiltered
contains no null values for author.