我有一个Convos表,其中包含许多消息。
我想要的是:提取所有重要信息和最后一条消息。通过last_message.created_at
订购convos
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"
这是不含
limit 1
的查询日志:Executing (default): SELECT "Convos"."id", "Convos"."sender_id", "Convos"."recipient_id", "Convos"."created_at", "Convos"."updated_at", "last_message"."id" AS "last_message.id", "last_message"."body" AS "last_message.body", "last_message"."read" AS "last_message.read", "last_message"."group_meeting_id" AS "last_message.group_meeting_id", "last_message"."user_id" AS "last_message.user_id", "last_message"."created_at" AS "last_message.created_at", "last_message"."updated_at" AS "last_message.updated_at", "last_message"."convo_id" AS "last_message.convo_id", "last_message->user"."id" AS "last_message.user.id", "last_message->user"."first_name" AS "last_message.user.first_name", "last_message->user"."avatar_file_name" AS "last_message.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" INNER JOIN "public"."msgs" AS "last_message" ON "Convos"."id" = "last_message"."convo_id" LEFT OUTER JOIN "public"."users" AS "last_message->user" ON "last_message"."user_id" = "last_message->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_message.created_at DESC LIMIT 10 OFFSET 70;
用
limit: 1
查询:Executing (default): SELECT "Convos"."id", "Convos"."sender_id", "Convos"."recipient_id", "Convos"."created_at", "Convos"."updated_at", "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"."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
谢谢!
最佳答案
免责声明:我不知道续集。并且-有3个文档版本,您尚未说明使用的是哪个版本。
我可以提供一个SQL(Postgres)解决方案。
我假设有一张convos表(类似):
CREATE TABLE convos (
id INT PRIMARY KEY,
sender_id INT,
recipient_id INT
);
和一个消息表
CREATE TABLE messages (
id INT PRIMARY KEY,
convo_id INT REFERENCES convos (id),
created_at timestamp without time zone
);
和一些测试数据:
INSERT INTO
convos (id, sender_id, recipient_id)
VALUES (1,1,1), (2,2,2), (3,3,4);
INSERT INTO
messages (id, convo_id, created_at)
VALUES
(1,1, '1990-07-24'),
(2,1, '2019-07-24'),
(3,2, '1990-07-24'),
(4,2, '2019-07-24'),
(5,3, null);
当您要查询
convos
表并从messages
表中获取最新消息时,您将不得不在子查询(或CTE或横向联接,...)中使用messages
的结果。例如:
SELECT
convos.sender_id,
convos.recipient_id,
messages.last_message_date
FROM convos
LEFT JOIN
(
SELECT convo_id, max(created_at) as last_message_date
FROM messages
GROUP BY convo_id
) messages ON convos.id=messages.convo_id
ORDER BY messages.last_message_date DESC
因此,对于sequelize.js-您必须找出它如何对关联模型进行子查询并使用结果。