从sequelize原始查询中仅获取dataValue,而不是Model实例

时间:2019-05-17 10:27:57

标签: database postgresql orm sequelize.js

我正在使用sequelize并使用原始查询从表中获取数据。但是,我只需要dataValues即可获取所有模型实例。 我的设置如下:

const sequelize = new Sequelize({
  database: process.env.PGDATABASE,
  username: process.env.PGUSER,
  password: process.env.PGPASS,
  host: process.env.PGHOST,
  port: process.env.PGPORT,
  dialect: "postgres"
});

getPostGres: () => {
    return sequelize;
  }

我查询数据库的方式如下:

let messageRatingsArr = await getPostGres().query(
    `SELECT mr.support_email, mr.support_name,
    (select count(mrn."chatId") as total FROM message_ratings as mrn WHERE mrn."ratingType"='NEGATIVE' and mr.support_email = mrn.support_email) as negative,
 (select count(mrp."chatId") as total FROM message_ratings as mrp WHERE mrp."ratingType"='POSITIVE' and mr.support_email = mrp.support_email) as positive,
 (select count(mrm."chatId") as total FROM message_ratings as mrm WHERE mrm."ratingType"='MIXED' and mr.support_email = mrm.support_email) as mixed,
 (select count(mru."chatId") as total FROM message_ratings as mru WHERE mru."ratingType"='NEUTRAL' and mr.support_email = mru.support_email) as neutral
      FROM message_ratings mr 
      WHERE mr."createdAt" >= '${properFromDate}' AND mr."createdAt" <= '${properToDate}'
     group by mr.support_email, mr.support_name 
     limit ${args.count} offset ${args.offset} `,
    {
      model: MessageRatingPG,
      mapToModel: true
    }
  );
  let messageRatings = messageRatingsArr.map(item=>{
    return item.dataValues;
  })
  let result = connectionFromArray(messageRatings, args);
  result.totalCount = messageRatings.length;
  return result;

如您所见,由于我正在映射来自查询的数据,其中包含诸如dataValues,_options,isNewRecord等各种各样的东西,因此如果我有大量数据集,则遍历数组是不高效的,因此我该怎么做才能只获取dataValues?

2 个答案:

答案 0 :(得分:1)

来自https://sequelize.org/master/manual/raw-queries.html

  

在不需要访问元数据的情况下,可以传递查询类型以告诉序列化如何格式化结果。例如,对于简单的选择查询,您可以执行以下操作:

sequelize.query("SELECT * FROM `users`", { type: sequelize.QueryTypes.SELECT})
  .then(users => {
    // We don't need spread here, since only the results will be returned for select queries
  })

现在,查看您的代码,并与文档中的下一段进行比较:

  

第二个选择是模型。如果您传递模型,则返回的数据将是该模型的实例。

// Callee is the model definition. This allows you to easily map a query to a predefined model
sequelize
  .query('SELECT * FROM projects', {
    model: Projects,
    mapToModel: true // pass true here if you have any mapped fields
  })
  .then(projects => {
    // Each record will now be an instance of Project
  })

我建议从您的原始代码中删除以下内容:

{
  model: MessageRatingPG,
  mapToModel: true
}

并用{ type: sequelize.QueryTypes.SELECT }

替换

答案 1 :(得分:0)

您必须在查询中添加属性raw。从docs

  

有时您可能会期望拥有一个庞大的数据集   显示,无需操纵。对于您选择的每一行,序列化   创建具有更新,删除,获取功能的实例   关联等。如果您有数千行,则可能需要一些时间   时间。如果您只需要原始数据而又不想更新任何内容,   您可以像这样获取原始数据。

 Project.findAll({ where: { ... }, raw: true })