Mongoose,使用find选择特定字段

198

我正在尝试仅选择特定字段

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

但是在我的 JSON 响应中,我也收到了 _id,而我的文档模式只有两个字段,即 _id 和名称。

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

为什么?

8个回答

296

_id字段始终存在,除非您明确排除它。可以使用-语法来实现这一点:

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

或通过对象显式地实现:

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

5
我认为.select只是在获取所有字段后进行筛选,我的建议是使用.find({}, 'name -_id') - hong4rc
5
@Hongarc .find({}, 'name -_id') 看起来无法正常工作? - Shanika Ediriweera
有没有一种方法可以直接获取值,而不需要一个对象,例如: [ 'value1', 'value2', 'value3' ] 而不是 [ 'name':'value1', 'name':'value2', 'name':'value3' ] - M.Amer
我使用这个时出现了错误,因为显然我不能同时使用包含和排除。我想我应该将此ID作为参数传递给.select()来排除它:.select({“_id”:0}) - Oriun

83

现在有一种更简便的方法:

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

如果您想要大部分的 Schema字段,并且只想省略几个字段,可以在字段名称前加上-(减号)。例如,在第二个参数中使用"-name"不会包括文档中的name字段,而此处给出的示例将仅返回返回文档中的name字段。


38
如果想要筛选多个字段,请不要用逗号分隔它们,直接用空格:blogItemModel.find({}, 'title intro_image intro_text publish_date', function(err, blog_items){.. - Starwave
1
对于那些想要在上述代码中使用where子句的人,可以这样写:dbSchema.Somevalue.find({userEmail:'test@test.com'},'userEmail -_id', function(err, someValue) - user2180794
1
多个字段将是 ['name', 'field2', 'field3', 'etc'],而不仅仅是 'name'。 - Eray T

35

使用Mongoose中的本地MongoDB代码处理它有更好的方法。

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/

注意:

var usersProjection

此处列出的对象列表将不会被返回/打印。


你如何使用findOne实现这个? - zero_cool
问卷需要在名称JSON数组上进行。使用您的方法,除了名称之外,其他键也会出现,例如年龄等。 - Ratan Uday Kumar
太棒了,正是我在寻找的。 - Shiva Teja

33

提示:0 表示忽略,1 表示显示。

示例 1:

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

例子2:

User.findById(id).select("_id, isActive").then(...)

例子3:

User.findById(id).select({ _id: 1, isActive: 1, name: 1, createdAt: 0 }).then(...)

安全性最适合的解决方案,无需任何附加功能! - J A S K I E R
似乎你不能再包含 0 和 1 的混合了。 - helloworld

21

数据库数据

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

查询

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

输出:

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

工作样例游乐场

链接


这个答案帮了我很多,它用易于理解的方式解释了问题,给你点赞。 - Nivethan

16

排除

以下代码将检索每个文档中除密码之外的所有字段:

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

输出

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

包括

以下代码将只检索每个文档中的电子邮件字段:

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

输出

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

5

实现这一点的精确方法是使用新的mongodbnodejs驱动程序中的.project()游标方法。

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

4
.project() 只适用于聚合操作。如果您想在查询(find)中使用它,请在 find({},{ name: 1, _id: 0 }) 方法的第二个参数中指定。 - Sham
使用新的MongoDB Node驱动程序,您必须使用这种方式。但是使用Mongoose,您可以使用第二个参数。 - Ashh
1
啊,它是在Node.js驱动程序中。 - Sham
不知道为什么,在新版本中@Anthony是正确的...在较低版本中,您可以这样做...非常混乱。 - ackuser

4
我在mongoose中找到了一个非常好的选项,它使用distinct返回文档中特定字段的所有数组。 User.find({}).distinct('email').then((err, emails) => { // do something })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接