序列化-如何通过关联的记录属性提取具有1个关联的记录和顺序的记录

时间:2019-07-17 17:52:20

标签: node.js sequelize.js

我有一个Convos表,其中包含许多消息。

我想要的是:提取所有重要信息和最后一条消息。通过last_message.created_at

订购convo
models.Convos.findAll({
    include: [
        {
            model: models.Messages,
            as: "last_message",
            order: [ [ 'created_at', 'DESC' ]],
            limit: 1,
         }
    ],
    where:{
        [Op.or]: [
            {
                sender_id: req.decoded.id
            },
            {
                recipient_id: req.decoded.id
            }
        ],
    },
)}

我最喜欢订购的是:

order: [
  [{model: models.Messages, as: 'last_message'}, 'created_at', 'DESC'],
],

但这会导致错误:

`Unhandled rejection SequelizeDatabaseError: missing FROM-clause entry for table "last_message"`

从这里开始,我猜测这个错误可能暗示有convos没有任何消息,从而使last_message.created_at不确定(尽管我可能完全误解了此错误)。

因此,从那里开始,我一直试图在where语句中添加一个子句,该子句仅提取具有至少1条消息的convos。这是我尝试过的一堆东西,它们都会引发错误:

添加到以下位置:

Sequelize.literal("`last_message`.`id` IS NOT NULL")


'$models.Messages.id$': { [Op.ne]: null },

Sequelize.fn("COUNT", Sequelize.col("last_message")): { [Op.gt]: 0 }
'$last_message.id$': { [Op.ne]: null }

'$last_message.id$': {
  [Op.ne]: null
}

我还尝试了having而不是where语句:

having: Sequelize.where(Sequelize.fn('COUNT', Sequelize.col('$last_message.id$')), '>=', 0)

如何根据相关记录last_message.created_at对convos进行正确排序?

更新-CONVOS模型的相关部分

"use strict";
module.exports = (sequelize, DataTypes) => {
  let Convos = sequelize.define(
    "Convos",
    {
      sender_id: {
        type: DataTypes.INTEGER,
        references: {
          model: "Users",
          key: "id"
        }
      },
      recipient_id: {
        type: DataTypes.INTEGER,
        references: {
          model: "Users",
          key: "id"
        }
      },
      created_at: DataTypes.DATE,
      updated_at: DataTypes.DATE
    },
    {
      timestamps: false,
      freezeTableName: true,
      schema: "public",
      tableName: "convos"
    }
  );

  Convos.associate = models => {
    Convos.hasMany(models.Messages, {
      as: "last_message",
      foreignKey: "convo_id",
      sourceKey: "id"
    });
  };

  return Convos;
};

更新 我已经知道相关模型具有limit时使用Sequelize.literal的问题。例如,这有效:

models.Convos.findAll({
  include: [
  {
        model: models.Messages,
        as: "last_message",
        order: [ [ 'created_at', 'DESC' ]],
        //limit: 1,
        required: true,
        duplicating: false, 
    },
],
where: {
  [Op.or]: [
      {
          sender_id: req.decoded.id
      },
      {
          recipient_id: req.decoded.id
      }
  ],
},
order: [[Sequelize.literal(`last_message.created_at`), 'DESC']],
offset: offset,
limit: 10,
}).then(convos => { ....

但是当我取消注释include部分中的limit: 1时,我得到了错误: Unhandled rejection SequelizeDatabaseError: missing FROM-clause entry for table "last_message"

这是查询日志:

Executing (default): SELECT "Convos"."id", "Convos"."sender_id", "Convos"."recipient_id", "Convos"."created_at", "Convos"."updated_at", "senderUser"."id" AS "senderUser.id", "senderUser"."email" AS "senderUser.email", "senderUser"."updated_at" AS "senderUser.updated_at", "senderUser"."first_name" AS "senderUser.first_name", "senderUser"."last_name" AS "senderUser.last_name", "senderUser"."bio" AS "senderUser.bio", "senderUser"."location" AS "senderUser.location", "senderUser"."avatar_file_name" AS "senderUser.avatar_file_name", "senderUser"."gender_id" AS "senderUser.gender_id", "senderUser"."nationality" AS "senderUser.nationality", "senderUser"."approved" AS "senderUser.approved", "senderUser"."status" AS "senderUser.status", "senderUser"."last_seen" AS "senderUser.last_seen", "senderUser"."birthyear" AS "senderUser.birthyear", "senderUser"."premium" AS "senderUser.premium", "senderUser"."basic_forever" AS "senderUser.basic_forever", "senderUser"."lat" AS "senderUser.lat", "senderUser"."lng" AS "senderUser.lng", "senderUser"."consecutive_days" AS "senderUser.consecutive_days", "senderUser"."total_days" AS "senderUser.total_days", "senderUser"."free_convos" AS "senderUser.free_convos", "senderUser"."gold_chat_credits" AS "senderUser.gold_chat_credits", "senderUser"."verified_chats_only" AS "senderUser.verified_chats_only", "recipientUser"."id" AS "recipientUser.id", "recipientUser"."email" AS "recipientUser.email", "recipientUser"."updated_at" AS "recipientUser.updated_at", "recipientUser"."first_name" AS "recipientUser.first_name", "recipientUser"."last_name" AS "recipientUser.last_name", "recipientUser"."bio" AS "recipientUser.bio", "recipientUser"."location" AS "recipientUser.location", "recipientUser"."avatar_file_name" AS "recipientUser.avatar_file_name", "recipientUser"."gender_id" AS "recipientUser.gender_id", "recipientUser"."nationality" AS "recipientUser.nationality", "recipientUser"."approved" AS "recipientUser.approved", "recipientUser"."status" AS "recipientUser.status", "recipientUser"."last_seen" AS "recipientUser.last_seen", "recipientUser"."birthyear" AS "recipientUser.birthyear", "recipientUser"."premium" AS "recipientUser.premium", "recipientUser"."basic_forever" AS "recipientUser.basic_forever", "recipientUser"."lat" AS "recipientUser.lat", "recipientUser"."lng" AS "recipientUser.lng", "recipientUser"."consecutive_days" AS "recipientUser.consecutive_days", "recipientUser"."total_days" AS "recipientUser.total_days", "recipientUser"."free_convos" AS "recipientUser.free_convos", "recipientUser"."gold_chat_credits" AS "recipientUser.gold_chat_credits", "recipientUser"."verified_chats_only" AS "recipientUser.verified_chats_only" FROM "public"."convos" AS "Convos" LEFT OUTER JOIN "public"."users" AS "senderUser" ON "Convos"."sender_id" = "senderUser"."id" LEFT OUTER JOIN "public"."users" AS "recipientUser" ON "Convos"."recipient_id" = "recipientUser"."id" WHERE ("Convos"."sender_id" = 32 OR "Convos"."recipient_id" = 32) ORDER BY last_message.created_at DESC LIMIT 10 OFFSET 0;

以下是一些有助于了解limit引起此问题的链接,但我仍然没有找到解决此问题的解决方案。

Link 1

Link 2

Link 3

Link 4

谢谢!

0 个答案:

没有答案