Mongoose, selecione um campo específico com encontrar


121

Estou tentando selecionar apenas um campo específico com

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);
    });
};

Mas na minha resposta json, estou recebendo também o _id, meu esquema de documento tem apenas dois campos, _id e nome

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

Por quê???

Respostas:


200

O _idcampo está sempre presente, a menos que você o exclua explicitamente. Faça isso usando a -sintaxe:

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);
    });
};

Ou explicitamente por meio de um objeto:

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);
    });
};

1
Acho que .selecté apenas um filtro para escolher o campo depois de obter tudo isso, minha recomendação é usar.find({}, 'name -_id')
hong4rc

3
@Hongarc .find({}, 'name -_id')parece não funcionar?
Shanika Ediriweera

existe uma maneira de obter o valor direto sem um obj como ['valor1', 'valor2', 'valor3'] em vez de ['nome': 'valor1', 'nome': 'valor2', 'nome': 'value3']
M.Amer

66

Existe uma maneira mais curta de fazer isso agora:

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
};

No caso de desejar a maior parte de Schema fieldse omitir apenas alguns, você pode prefixar o campo namecom um -. Por ex, "-name"no segundo argumento não incluirá o namecampo no documento, enquanto o exemplo fornecido aqui terá apenas o namecampo nos documentos retornados.


27
Para aqueles que desejam filtrar vários campos, não os separe com vírgulas, apenas espaço:blogItemModel.find({}, 'title intro_image intro_text publish_date', function(err, blog_items){..
Starwave

1
para aqueles que desejam usar a cláusula where em dbSchema.Somevalue.find ({userEmail:'test@test.com '},' userEmail -_id ', function (err, someValue)
user2180794

1
vários campos seriam ['nome', 'campo2', 'campo3', 'etc'] em vez de apenas 'nome'
Eray T

24

Há uma maneira melhor de lidar com isso usando o código Native MongoDB no 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/

Nota:

var usersProjection

A lista de objetos listados aqui não será devolvida / impressa.


Como você faz isso com findOne?
zero_cool

necessidades de questionário no array name json. com seu método, outras chaves estão lá, mas também virão como idade, etc.
Ratan Uday Kumar

Incrível, exatamente o que eu estava procurando
Teja

9

Dados DB

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

Inquerir

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

Resultado:

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

Amostra de playground de trabalho

ligação


4

Excluir

O código abaixo irá recuperar todos os campos, exceto senha, em cada documento:

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

Resultado

[
  {
    "_id": "5dd3fb12b40da214026e0658",
    "email": "example@example.com"
  }
]

Incluir

O código abaixo só recuperará o campo de e-mail em cada documento:

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

Resultado

[
  {
    "email": "example@example.com"
  }
]

3

A maneira precisa de fazer isso é usar o .project()método do cursor com o novo driver mongodbe nodejs.

var query = await dbSchemas.SomeValue.find({}).project({ name: 1, _id: 0 })

3
.project()funciona apenas com agregado. Se você quiser usá-lo com find, use o segundo argumento no find({},{ name: 1, _id: 0 })método.
Sham

Não com o novo driver de nó mongodb, você deve usar desta forma. Mas com o mangusto você pode usar o segundo argumento.
Ashh

1
ah, está no driver nodejs.
Sham

Não entendo o porquê, mas nas novas versões @Anthony está certo ... Versões inferiores você pode fazer desta forma ... muito confuso
ackuser

2

Por exemplo,

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

0 significa ignorar

1 significa mostrar

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.