Mongoose, wybierz określone pole za pomocą funkcji find

121

Próbuję wybrać tylko określone pole za pomocą

exports.someValue = function(req, res, next) {
    //query with mongoose
    var query = dbSchemas.SomeValue.find({}).select('name');

    query.exec(function (err, someValue) {
        if (err) return next(err);
        res.send(someValue);
    });
};

Ale w mojej odpowiedzi json otrzymuję również _id, mój schemat dokumentu ma tylko dwa pola, _id i nazwę

[{"_id":70672,"name":"SOME VALUE 1"},{"_id":71327,"name":"SOME VALUE 2"}]

Czemu???

TlonXP
źródło

Odpowiedzi:

201

_idPole jest zawsze obecny, chyba że wyraźnie wyklucza go. Zrób to, używając -składni:

exports.someValue = function(req, res, next) {
    //query with mongoose
    var query = dbSchemas.SomeValue.find({}).select('name -_id');

    query.exec(function (err, someValue) {
        if (err) return next(err);
        res.send(someValue);
    });
};

Lub bezpośrednio za pomocą obiektu:

exports.someValue = function(req, res, next) {
    //query with mongoose
    var query = dbSchemas.SomeValue.find({}).select({ "name": 1, "_id": 0});

    query.exec(function (err, someValue) {
        if (err) return next(err);
        res.send(someValue);
    });
};
Neil Lunn
źródło
1
Myślę, że .selectpo prostu jest to filtr do wyboru pola po tym, jak to wszystko zdobędziesz, .find({}, 'name -_id')
radzę
3
@Hongarc .find({}, 'name -_id')nie działa?
Shanika Ediriweera
czy istnieje sposób na bezpośrednie pobranie wartości bez obiektu, takiego jak [„wartość1”, „wartość2”, „wartość3”] zamiast [„nazwa”: „wartość1”, „nazwa”: „wartość2”, „nazwa”: 'value3']
M.Amer
67

Teraz jest na to krótszy sposób:

exports.someValue = function(req, res, next) {
    //query with mongoose
    dbSchemas.SomeValue.find({}, 'name', function(err, someValue){
      if(err) return next(err);
      res.send(someValue);
    });
    //this eliminates the .select() and .exec() methods
};

W przypadku, gdy chcesz większość Schema fieldsi chcą pominąć tylko kilka, można poprzedzić pola namez -. Ex "-name"w drugim argumencie będzie nie zawierają namepola w dokumencie natomiast przykład podano tutaj będą miały jedynie na namepolu w zwracanych dokumentów.

Akash
źródło
28
Dla tych, którzy chcą filtrować wiele pól, nie oddzielaj ich przecinkiem, tylko zwykłą spacją:blogItemModel.find({}, 'title intro_image intro_text publish_date', function(err, blog_items){..
Starwave
1
dla tych, którzy chcą użyć klauzuli gdzie w powyższym dbSchema.Somevalue.find ({userEmail:'[email protected] '},' userEmail -_id ', function (err, someValue)
user2180794
1
wiele pól to [„nazwa”, „pole 2”, „pole 3”, „itp.”] zamiast tylko „nazwa”
Eray T
24

Jest lepszy sposób na obsługę tego przy użyciu kodu natywnego MongoDB w Mongoose.

exports.getUsers = function(req, res, next) {

    var usersProjection = { 
        __v: false,
        _id: false
    };

    User.find({}, usersProjection, function (err, users) {
        if (err) return next(err);
        res.json(users);
    });    
}

http://docs.mongodb.org/manual/reference/method/db.collection.find/

Uwaga:

var usersProjection

Lista obiektów wymienionych tutaj nie zostanie zwrócona / wydrukowana.

ElvinD
źródło
Jak to robisz z findOne?
zero_cool,
kwestionariusz potrzebuje tablicy nazw json. z twoją metodą są tam inne klucze, niż one przyjdą jak wiek itp.
Ratan Uday Kumar
Niesamowite, właśnie to, czego szukałem
Teja
9

Dane DB

[
  {
    "_id": "70001",
    "name": "peter"
  },
  {
    "_id": "70002",
    "name": "john"
  },
  {
    "_id": "70003",
    "name": "joseph"
  }
]

Pytanie

db.collection.find({},
{
  "_id": 0,
  "name": 1
}).exec((Result)=>{
    console.log(Result);
})

Wynik:

[
  {
    "name": "peter"
  },
  {
    "name": "john"
  },
  {
    "name": "joseph"
  }
]

Działający przykładowy plac zabaw

połączyć

Ratan Uday Kumar
źródło
4

Wykluczać

Poniższy kod pobierze wszystkie pola inne niż hasło w każdym dokumencie:

const users = await UserModel.find({}, {
  password: 0 
});
console.log(users);

Wynik

[
  {
    "_id": "5dd3fb12b40da214026e0658",
    "email": "[email protected]"
  }
]

Zawierać

Poniższy kod pobierze tylko pole e-mail w każdym dokumencie:

const users = await UserModel.find({}, {
  email: 1
});
console.log(users);

Wynik

[
  {
    "email": "[email protected]"
  }
]
Zeeshan Ahmad
źródło
3

Dokładnym sposobem na to jest użycie .project()metody kursora z new mongodbi nodejsdriver.

var query = await dbSchemas.SomeValue.find({}).project({ name: 1, _id: 0 })
Ashh
źródło
3
.project()działa tylko z kruszywem. Jeśli chcesz go użyć z find, użyj drugiego argumentu w find({},{ name: 1, _id: 0 })metodzie.
Sham
Nie, z nowym sterownikiem węzła mongodb musisz używać tego sposobu. Ale w przypadku mangusty możesz użyć drugiego argumentu.
Ashh,
1
ah, jest w sterowniku nodejs.
Sham
Nie rozumiem dlaczego, ale w nowych wersjach @Anthony ma rację ... W niższych wersjach można to zrobić w ten sposób ... bardzo niechlujnie
Ackuser
2

Na przykład,

User.find({}, { createdAt: 0, updatedAt: 0, isActive: 0, _id : 1 }).then(...)

0 oznacza ignorować

1 oznacza pokaż

Nishant Shah
źródło