序列化-包括关联记录正在复制返回的记录

时间:2019-08-20 20:10:56

标签: node.js sequelize.js

我有一个convos模型,其中包含许多消息。我想获取每个用户的convos和最后一条消息,并按last_message.created_at对返回的结果进行排序。问题在于,对于每条消息,它都会返回一个convo实例。因此,一个包含10条消息的convo,我得到10条convo记录,但是每个记录都有不同的last_message。如何只拉出1个convo,并只包含1条消息,即最新的created_at消息。

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.hasOne(models.Messages, {
      as: "last_msg",
      foreignKey: {
        name: "convo_id",
        allowNull: false
      },
      constraints: false,
      sourceKey: "id",
    });
    Convos.belongsTo(models.Users, {
      as: "senderUser",
      targetKey: "id",
      foreignKey: "sender_id"
    });
    Convos.belongsTo(models.Users, {
      as: "recipientUser",
      targetKey: "id",
      foreignKey: "recipient_id"
    });
  };

  return Convos;
};

消息模型

module.exports = (sequelize, DataTypes) => {
    let Messages = sequelize.define(
        "Messages",
        {
            body: DataTypes.STRING,
            read: DataTypes.BOOLEAN,
            group_meeting_id: {
                type: DataTypes.INTEGER,
                references: {
                    model: "GroupConvos",
                    key: "id"
                }
            },
            // user_id: DataTypes.INTEGER,
            user_id: {
                type: DataTypes.INTEGER,
                references: {
                    model: "Users",
                    key: "id"
                }
            },
            created_at: DataTypes.DATE,
            updated_at: DataTypes.DATE,
            convo_id: {
                type: DataTypes.INTEGER,
                references: {
                    model: "Convos",
                    key: "id"
                }
            }
        },
        {
            timestamps: false,
            freezeTableName: true,
            schema: "public",
            tableName: "msgs"
        }
    );

    Messages.associate = models => {
        Messages.belongsTo(models.Users, {
            as: "user",
            targetKey: "id",
            foreignKey: "user_id",
            constrains: true
        });
    };

    return Messages;
};

查询:

 models.Convos.findAll({
    include: [
        {
            model: models.Messages,
            as: "last_msg",
            order: [ [ 'created_at', 'DESC' ]],
            attributes: [
              'convo_id',
              'body',
              'read',
              'created_at'
            ],
            include: [
                {
                    model: models.Users,
                    as: 'user',
                    attributes: [
                          'id',
                          'first_name',
                          'avatar_file_name',
                    ]

                }
            ],

        },
        {
          model: models.Users,
          as: 'senderUser',
          attributes: [
                'id',
                'first_name',
                'avatar_file_name'
          ]
        },
        {
          model: models.Users,
          as: 'recipientUser',
          attributes: [
                'id',
                'first_name',
                'avatar_file_name'
          ]
        },
    ],
    where: {
      [Op.or]: [
          {
              sender_id: req.decoded.id
          },
          {
              recipient_id: req.decoded.id
          }
      ],
    },
    order: [[Sequelize.literal(`last_msg.created_at`), 'DESC']],
    offset: offset,
    limit: 10,
}).then(convos => {
    res.status(200).json({status: 200, data: convos}); 
})

这将产生:

Executing (default): SELECT "Convos"."id", "Convos"."sender_id", "Convos"."recipient_id", "Convos"."created_at", "Convos"."updated_at", "last_msg"."id" AS "last_msg.id", "last_msg"."convo_id" AS "last_msg.convo_id", "last_msg"."body" AS "last_msg.body", "last_msg"."read" AS "last_msg.read", "last_msg"."created_at" AS "last_msg.created_at", "last_msg->user"."id" AS "last_msg.user.id", "last_msg->user"."first_name" AS "last_msg.user.first_name", "last_msg->user"."avatar_file_name" AS "last_msg.user.avatar_file_name", "senderUser"."id" AS "senderUser.id", "senderUser"."first_name" AS "senderUser.first_name", "senderUser"."avatar_file_name" AS "senderUser.avatar_file_name", "recipientUser"."id" AS "recipientUser.id", "recipientUser"."first_name" AS "recipientUser.first_name", "recipientUser"."avatar_file_name" AS "recipientUser.avatar_file_name" FROM "public"."convos" AS "Convos" LEFT OUTER JOIN "public"."msgs" AS "last_msg" ON "Convos"."id" = "last_msg"."convo_id" LEFT OUTER JOIN "public"."users" AS "last_msg->user" ON "last_msg"."user_id" = "last_msg->user"."id" 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_msg.created_at DESC LIMIT 10 OFFSET 0;

这将返回例如:

Convo {id: 1, last_msg: { id: 2 }}
Convo {id: 1, last_msg: { id: 3 }}
Convo {id: 1, last_msg: { id: 4 }}

我只希望每个convo具有最后一个味精-不希望convo中的每个消息都具有相同的convo。

0 个答案:

没有答案