Sequelizejs findAll 排除字段

Whi*_*her 4 node.js sequelize.js

我知道options.attributes你列出了你想要选择的属性,但有没有办法只排除一个字段?

到目前为止,我已经解决了

User
  .findAll({order: [['id','DESC']]})
  .then(function(users) {
    users = users.filter(function(user){
      delete user.dataValues.password;
      return user;
    });
    return reply( ReplyUtil.ok(users) );
  })
  .catch(function(err){
    return reply( ReplyUtil.badImplementation(err) );
  });
Run Code Online (Sandbox Code Playgroud)

顺便提一句

我不明白为什么你应该使用user.dataValues.password if not delete 不起作用,而不是简单地user.password 如果我像这样调试console.log('pass: ', user.password)我可以看到密码。

gdu*_*duh 12

是的,可以排除字段,就像这样:

User
  .findAll({
    attributes: {exclude: ['password']},
    order: [['id','DESC']]})
  .then( users => {
    return reply( ReplyUtil.ok(users) );
  })
  .catch( err => {
    return reply( ReplyUtil.badImplementation(err) );
  });
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅https://sequelize.org/master/manual/querying.html


San*_*yrm 8

如果您有权访问模型定义,一种方法(在撰写本文时在v6 Sequelize中可用)是利用defaultScope. 这提供了一种定义如何返回所有响应的方法(默认情况下),从而避免在每次使用中重复过滤器。例如:

User.init(
  {...},  // Model fields
  {       // Options
    sequelize, 
    modelName: 'User',
    defaultScope: {
      attributes: {
        exclude: ['password']
      },
      order: [['id', 'DESC']]
    },
    scopes: {
      withPassword: {
        attributes: {
          include: ['password']
        }
      }
    }
  }
)
Run Code Online (Sandbox Code Playgroud)

在示例中,adefaultScope被定义为排除该字段,并提供了password一个自定义范围以再次包含该字段,以供明确需要的情况。password这些可以称为:

// Has no password field in results:
User.findAll();

// Has password field in results:
User.scope('withPassword').findAll();
Run Code Online (Sandbox Code Playgroud)

范围很有用,但它defaultScope是唯一的,因为它是唯一修改基本查询结果的范围。范围内还有其他几个选项可用于进一步自定义结果结构。

注意:手动指定 时.scope(...),它将删除defaultScope, 使用.scope(['defaultScope', ...])以确保包含它。例如:

User.scope(['defaultScope','active','withEmployer']).findAll();
Run Code Online (Sandbox Code Playgroud)


Wag*_*rin 2

我知道这是一个旧帖子。但我因为同样的问题来到这里,我相信会有更多的人来。因此,在研究了 stackoverflow 上的一些帖子后,我发现最简单的方法是使用函数select来指定我们不想返回的字段。所以它的功能看起来像这样:

User
  .findAll({order: [['id','DESC']]}).select('-password')
  .then(function(users) {
    return reply( ReplyUtil.ok(users) );
  })
  .catch(function(err){
    return reply( ReplyUtil.badImplementation(err) );
  });
Run Code Online (Sandbox Code Playgroud)

另一种方法是更改​​模型(通过代码,我假设您使用 mongoose 或sequelize 指定了此模型)。您可以像这样指定该字段:password: { type: String, select: false }。默认情况下,此选择将​​导致数据库中的任何查询都不会返回密码。除非你使用前面的函数在查询中添加密码(select ('+ password') )。

为了回答您的主要问题,Mongoose 和 Sequelize 将其所有返回值包装在包含元数据的虚拟对象中。如果你有一个对象并且只想要未修饰的对象,则必须打开它们,如下所示:

Model.findById(1).then(data => {
  console.log(data.get({ plain: true }));
});
Run Code Online (Sandbox Code Playgroud)

如果您只想打印对象,可以使用 .toJSON:

Model.findById(1).then(data => {
  console.log(data.toJSON);
});
Run Code Online (Sandbox Code Playgroud)

如果您只想要数据而不是模型实例,您可以这样做:

Model.findAll({
  raw: true
});
Run Code Online (Sandbox Code Playgroud)