How to exclude one particular field from a collection in Mongoose?

I have a NodeJS application with Mongoose ODM(Mongoose 3.3.1). I want to retrieve all fields except 1 from my collection.For Example: I have a collection Product Which have 6 fields,I want to select all except a field "Image" . I used "exclude" method, but got error.. This was my code.

    var Query = models.Product.find();
Query.exclude('title Image');


if (req.params.id) {
Query.where('_id', req.params.id);
}




Query.exec(function (err, product) {
if (!err) {
return res.send({ 'statusCode': 200, 'statusText': 'OK', 'data': product });
} else {
return res.send(500);
}
});

But this returns error

Express
500 TypeError: Object #<Query> has no method 'exclude'.........

Also I tried, var Query = models.Product.find().exclude('title','Image'); and var Query = models.Product.find({}).exclude('title','Image'); But getting the same error. How to exclude one/(two) particular fields from a collection in Mongoose.

94750 次浏览

I don't know where you read about that .exclude function, because I can't find it in any documentation.

But you can exclude fields by using the second parameter of the find method.

Here is an example from the official documentation:

db.inventory.find( { type: 'food' }, { type:0 } )

This operation returns all documents where the value of the type field is food, but does not include the type field in the output.

Use query.select for field selection in the current (3.x) Mongoose builds.

Prefix a field name you want to exclude with a -; so in your case:

Query.select('-Image');

Quick aside: in JavaScript, variables starting with a capital letter should be reserved for constructor functions. So consider renaming Query as query in your code.

Model.findOne({ _id: Your Id}, { password: 0, name: 0 }, function(err, user){
// put your code
});

this code worked in my project. Thanks!! have a nice day.

You could do this

const products = await Product.find().select(['-image'])

In the updated version of Mongoose you can use it in this way as below to get selected fields.

user.findById({_id: req.body.id}, 'username phno address').then(response => {
res.status(200).json({
result: true,
details: response
});
}).catch(err => {
res.status(500).json({ result: false });
});

I am use this with async await

async (req, res) => {
try {
await User.findById(req.user,'name email',(err, user) => {
if(err || !user){
return res.status(404)
} else {
return res.status(200).json({
user,
});
}
});
} catch (error) {
console.log(error);
}

I'm working on a feature. I store a userId array name "collectedUser" than who is collected the project. And I just want to return a field "isCollected" instead of "collectedUsers". So select is not what I want. But I got this solution.

This is after I get projects from database, I add "isCollected".

for (const item of projects) {
item.set("isCollected", item.collectedUsers.includes(userId), {
strict: false,
})
}

And this is in Decorator @Schema

@Schema({
timestamps: true,
toObject: {
virtuals: true,
versionKey: false,
transform: (doc, ret, options): Partial<Project> => {
return {
...ret,
projectManagers: undefined,
projectMembers: undefined,
collectedUsers: undefined
}
}
}
})

Finally in my controller

projects = projects.map(i => i.toObject())

It's a strange tricks that set undefined, but it really work.

Btw I'm using nestjs.

You can do it like this

const products = await Product.find().select({
"image": 0
});

For anyone looking for a way to always omit a field - more like a global option rather than doing so in the query e.g. a password field, using a getter that returns undefined also works

{
password: {
type: String,
required: true,
get: () => undefined,
},
}

NB: Getters must be enabled with option { toObject: { getters:true } }

you can exclude the field from the schema definition by adding the attribute

    excludedField : {
...
select: false,
...
}

whenever you want to add it to your result, add this to your find()

find().select('+excludedFiled')