65

I'm pretty confused with the use of the select method. This is how I use it, and it's wrong:

Transaction.find({username : user.username}).select('uniqueId', 'confirmation_link', 'item_name', 'timeout', 'username', function(err, txs){
        callback(txs);
});

What I'm trying to achieve is simply to select from the transactions in the database the ones with that username and I want to take out just the fields listed in the select method. Can anyone point out how should I use the select method? Thanks.

Masiar
  • 20,450
  • 31
  • 97
  • 140

12 Answers12

95

the docs say you can achieve this like so:

Mongoose v4.0

// Retrieving only certain fields

Model.find({}, 'first last', function (err, docs) {

});

old outdated API

// Retrieving only certain fields

Model.find({}, ['first', 'last'], function (err, docs) {
  // docs is an array of partially-`init`d documents
  // defaults are still applied and will be "populated"
});

so you can do this without select().

ruwan800
  • 1,567
  • 17
  • 21
Philipp Kyeck
  • 18,402
  • 15
  • 86
  • 123
  • 4
    It seems this approach is working, but still in `docs` I end up having fields like `_id` which I don't want to have. – Masiar Mar 04 '12 at 10:22
  • 1
    any other field besides `_id` that you don't ask for? if not, i'd think that `_id` is an exception and thus always returned... but this is just a guess – Philipp Kyeck Mar 04 '12 at 23:03
  • Well actually all the fields asked are all the fields except the `_id` field. And I don't want it. Is there a way to avoid this? – Masiar Mar 05 '12 at 14:40
  • then why don't you just ignore the `_id`? – Philipp Kyeck Mar 05 '12 at 19:52
  • The problem is that the object I receive is passed to a client library that has some problem processing the field `_id`. I would like to remove it, I already tried with `delete txs[i]["_id"]` inside a loop but it still appears. I can't believe there is no way to do a selective query in Mongoose. – Masiar Mar 05 '12 at 21:49
  • 2
    Mongo (not mongoose) automatically returns _id for a find unless you explicitly tell it not to. In mongo, you can just ad _id: false to your projection to not return it, but I don't know what that correlates to (if anything) in mongoose. – tandrewnichols Feb 12 '13 at 13:17
  • BTW, if you really want to control what gets to the client, the best approach is to whitelist which parts of the data structure go through. There's an npm module named "screener" for that: https://github.com/RushPL/node-screener – Aleksander Adamowski Aug 02 '13 at 16:51
  • @pkyeck It looks like the second argument to Model.find has changed. Now it should be a string with the field names separated by spaces. So the complete line now should be something like: `Model.find({}, 'first last', function (err, docs) {`. – Dennis van der Schagt May 13 '15 at 14:27
  • How can I do this while fetching multiple rows? Ex: `User.find({ '_id': { $in: ['someid', 'someid'] } },` Here I tried the same method but it is fetching for the first record only. – Arpit Kumar Feb 25 '17 at 11:22
  • 1
    To just exclude the `_id` field, you could add it to the select string with a minus, like this: `Model.find({}, '-_id', function (err, docs)` – Lyubomir Vasilev Jan 13 '19 at 21:25
  • can we rename the fields upon fetching? Like `select('user.name as name')` or something similar? – HexaCrop Oct 27 '20 at 06:57
25

this is another way: queries in mongoose

Transaction.find({username : user.username})
.select('uniqueId confirmation_link item_name timeout username')
.exec(function(err, txs) {
        console.log(txs);
});
lee
  • 386
  • 5
  • 5
  • 3
    This works well. If you want to exclude a field, you can just do .select("-field_I_dont_want") – Farasi78 Mar 13 '19 at 16:26
  • Not working on type: Object fields `passbase_webhook: { type: Object, select: false }` eg . `select(passbase_webhook.status)` where status is key in my object` – Abhi Burk Oct 11 '21 at 04:39
20

Now there is a shorter way of doing this (not using .select and not using an array), just passing the fields separate by spaces as the second argument

User.find({}, 'first last', function (err, usr) {
    //Got the result, saved a few bytes of code
});

The Docs

Felipe Pereira
  • 11,410
  • 4
  • 41
  • 45
19

Select method is used to select which fields are to be returned in the query result, excluding select means we want all the other fields to be returned, here is simple usage as per the docs.

// include a and b, exclude other fields  
query.select('a b');

// exclude c and d, include other fields  
query.select('-c -d');

More information here, https://mongoosejs.com/docs/api.html#query_Query-select

Mayank
  • 191
  • 1
  • 4
13

To retrieve certain fields without retrieving the '_id' you can specify to exclude it

Model.find({}, {'Username':1, '_id':0}, function ( err, docs ){}.....
Alex Stubbs
  • 151
  • 1
  • 3
10

This was pretty helpful: How to protect the password field in Mongoose/MongoDB so it won't return in a query when I populate collections?

Looks like you have a few options.

1) Use select('-_id'). 2) Use find({whatever: values}, '-_id', callback...}. I can't verify this method, but if it works with select(), I don't see why it wouldn't work here.

Community
  • 1
  • 1
tandrewnichols
  • 3,456
  • 1
  • 28
  • 33
6

To retrieve specific fields only, use the following,

Model.find({/*Your query*/}, {'firstName':1, 'lastname':1, '_id':0}, //Notice, this will omit _id! function ( err, docs ){}.....

that will work and will NOT bring in any extra id such as _id.

Zack S
  • 1,412
  • 1
  • 23
  • 37
4

selection & projection operation can be done in this way easyly in nodejs. Try this

    var Selection={
        <some key of data model > : <target value for that key field>,
        <some key of data model > : <target value for that key field>
        //you can add many parameters here selection operation
        };
    var Projection = {
        __v    : false,
        _id    : false
        //you can add many parameters here for projection
    };
    <DataModel>.find(Selection,Projection,function (err,data) {
        if(err){
            console.log(err);
        }else{
         console.log(data);
        }
    });
Chanaka Fernando
  • 2,176
  • 19
  • 19
1

This syntax Also works

Transaction.find({username : user.username}).select(['uniqueId', 'confirmation_link', 'item_name', 'timeout', 'username']);
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Mueed
  • 31
  • 5
  • Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P May 20 '22 at 14:39
0

Remove the commas and quotes between the fields you want to select:

Transaction.find({username : user.username}).select('uniqueId confirmation_link item_name timeout username', function(err, txs){
    callback(txs);
});
Hasta Dhana
  • 4,699
  • 7
  • 17
  • 26
Eric
  • 9
  • 1
0

set select: false for the fields that you want to exclude in your Schema on server request.

example

const userSchema = mongoose.Schema({
    name: {
        type: String,
        select: false
    },

    password: {
        type: Number,
        select: false

    }
})

that way the only fields that you want coming in should be the ones without select: false

If for some reason you need to get the password(any field) but need to have select: false in the schema. use select('+password etc')

0

.select() method is used to specify which fields you want to include or exclude from the query results. You can use a string value in parenthesis to specify which tags to use, the - operator when used in a string value can be used to exclude, while the use of the + operator in the string can be used to force inclusion of said query string I believe this is a mongoose method.