我有一个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。