Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

Sequelize 聊天列表group查询

做了聊天室的功能
表是这样设计的

id: { type: UUID, primaryKey: true, defaultValue: UUIDV1 },
fromUserId: { type: UUID, allowNull: false },
toUserId: { type: UUID, allowNull: false },
message: { type: STRING, allowNull: false },
isReaded: { type: BOOLEAN, allowNull: false, defaultValue: false },
createdAt: DATE,
updatedAt: DATE,
 deletedAt: DATE

然后我要查当前用户的所有聊天者,就是微信的聊天列表

我是这样写的

const datas = await ctx.model.Chat.findAndCountAll({
        where:{
            [ctx.model.Sequelize.Op.or]:[
                { toUserId: ctx.user.id},
                { fromUserId: ctx.user.id}
            ]
        },
        group: ['toUserId', 'fromUserId'],
    })

然后有会发现,跟一个用户会有两个聊天框,一个是他发我最后一条信息,和我发给他的最后一条信息:

image

我要怎么合并这两个呢?根据最后的发表时间


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Sequelize语法不清楚,但可以分享下需求对应的SQL,看是否对你有帮助。(注:sql中的@uid替换为要查询哪个用户的聊天列表的user id)
1.第一种,比较简单

select DISTINCT(if(fromUserId=`@uid`,toUserId,fromUserId)) uid,max(id) 
from chat 
where fromUserId=`@uid` or toUserId=`@uid` group by uid;

但如果聊天表chat数据量越来越大,可能会执行比较久。
主要聚合的是uid,并且要取到对方的uid,所以使用了if(发送方是自己,选择接收方id,否则选择发送方id);最后max查出最后一条的id(正常就是最后发送的时间)。
有了用户的uid和聊天表的id,那剩下的就是去关联用户表和聊天表,取出对应用户信息和聊天信息了。

2.第二种,速度比较快,有点复杂

select uid,max(max_id) as id from (
 select toUserId as uid,max(id) as max_id from chat where fromUserId=`@uid` group by toUserId
 union all
 select fromUserId as uid,max(id) as max_id from chat where toUserId=`@uid` group by fromUserId
)t group by uid

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...