Mongoose retrieving data without _id field

node.jsMongoose

node.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' because typeof id === 'string', not ObjectId.
  • 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 an id 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
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMasiarView Question on Stackoverflow
Solution 1 - node.jsVisioNView Answer on Stackoverflow
Solution 2 - node.jsdanmactoughView Answer on Stackoverflow
Solution 3 - node.jsGábor ImreView Answer on Stackoverflow
Solution 4 - node.jsDurjaView Answer on Stackoverflow