Mongoose retrieving data without _id field
node.jsMongoosenode.js Problem Overview
I would like to retrieve some data from a Mongoose setting in my Node.js application. I noticed that no matter what I write as field selection, I always get the _id
field. Is there a way not to fetch it?
This is how I do right now:
Transaction.find({username : user.username}, ['uniqueId', 'timeout', 'confirmation_link', 'item_name'], function(err, txs){
console.log("user : " + user.username + " with txs: " + txs);
callback(txs);
});
And logs me the results which contain the _id
field.
node.js Solutions
Solution 1 - node.js
Another way is to use text argument with prefix -
which will exclude this or that field from the result:
Entity.find({ ... }, '-_id field1 field2', function(err, entity) {
console.log(entity); // { field1: '...', field2: '...' }
});
Solution 2 - node.js
_id
must be specifically excluded. For example,
Transaction.find({username : user.username}, { '_id': 0, 'uniqueId' :1, 'timeout': 1, 'confirmation_link': 1, 'item_name': 1}, function(err, txs){
console.log("user : " + user.username + " with txs: " + txs);
callback(txs);
});
Solution 3 - node.js
Another approach:
- Augment the
.toJSON()
of the schema that it deletes the_id
and the__v
fields - Call
.toJSON()
on all DB objects sent to client - Extra benefit #1: you can use
item.id === 'something'
becausetypeof id === 'string'
, notObjectId
. - Extra benefit #2: When you got gan object back from the client and you want to search / update then you don't have to manually delete
_id
because there is none, just anid
which is ignored.
Augmenting JSON:
mySchema.set('toJSON', {
virtuals: true,
transform: (doc, ret, options) => {
delete ret.__v;
ret.id = ret._id.toString();
delete ret._id;
},
});
So you can use:
let item = (await MyCollection.findOne({/* search */}).exec()).toJSON();
if (item.id === 'someString') return item;
I know it's ugly. But it's the best bad idea that I have so far.
Solution 4 - node.js
In 5.2.13 version of Mongoose (Sept 2018)- using the query builder approach the same can be converted to
async function getUserDetails(user) {
try {
if (!user || !user.name) return;
const result = await Transaction.
find({username : user.username}).
select('uniqueId timeout confirmation_link item_name -_id');
// Adding minus sign before the _id (like -_id) in the select string unselects the _id which is sent by default.
console.log(result);
} catch(ex) {
return ex
}
}