【问题标题】:Get only dataValues from sequelize raw query instead of Model instance仅从 sequelize 原始查询而不是模型实例中获取 dataValues
【发布时间】:2019-05-17 10:27:57
【问题描述】:

我正在使用 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?

【问题讨论】:

    标签: database postgresql orm sequelize.js


    【解决方案1】:

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

    如果您不需要访问元数据,您可以传入查询类型来告诉 sequelize 如何格式化结果。例如,对于一个简单的选择查询,您可以这样做:

    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 }

    【讨论】:

      【解决方案2】:

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

      有时您可能会期待一个您想要的海量数据集 显示,无需操纵。对于您选择的每一行,Sequelize 创建具有更新、删除、获取功能的实例 关联等。如果您有数千行,这可能需要一些 时间。如果您只需要原始数据并且不想更新任何内容, 你可以这样做来获取原始数据。

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

      【讨论】:

      • OP 显然使用.query() 来写出他的原始查询。这与您建议的Model.findAll() 不兼容。
      猜你喜欢
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多