I have a schema:
const LinkSchema = new mongoose.Schema({
name: { type: String },
style: { default: "icon", type: String },
});
And a document already in mongoDB with potentially many old fields.
{
"name": "abcLink",
"oldThing1": true,
"oldThing2": "oeunth",
....
"oldThing100": "hi",
}
I want link.findOne({ name: "abcLink" })
to return
{
"name": "abcLink",
"style": "icon"
}
Currently, I get
{
"name": "abcLink",
"oldThing": true,
"style": "icon"
}
How can I have strict
reads to get back a filtered object where any fields not defined in the schema are not returned?
Because we have 30+ active fields and many inactive fields, it's important that we can define the schema once and then automatically filter the results. We do not want to duplicate the valid or invalid fields in multiple places. Note: Using a function like Object.keys
on the schema to get an array of the valid fields and using that to filter is perfectly acceptable.
You can override the toJSON
method using the transform function like this so that it doesn't have any fields not in the schema.
const mongoose = require("mongoose");
const LinkSchema = new mongoose.Schema({
name: { type: String },
style: { default: "icon", type: String }
});
var schemaFields = Object.keys(LinkSchema.paths);
LinkSchema.set("toJSON", {
transform: function(doc, ret, options) {
let result = {};
Object.keys(ret).map(key => {
if (schemaFields.includes(key)) {
result[key] = ret[key];
}
});
return result;
}
});
module.exports = mongoose.model("Link", LinkSchema);
Update as @Loren mentioned in the comments, for the nested objects we can use Object.keys(LinkSchema.tree)
instead of Object.keys(LinkSchema.paths)
.